如何在php中检查数组是否已经排序

6

我有一个小的php任务。我有一个简单的数组。

Array
(
    [0] => 50
    [1] => 100
    [2] => 150

)

有没有内置的 PHP 函数,可以判断数组是否已经排序好了,并且能够返回 true 或 false。或者有没有其他不需要使用循环的 PHP 脚本来实现这个功能。我知道用循环和条件语句实现会比较简单。


3
当你知道答案的时候,问这个问题很容易,为什么还要问呢? - KingCrunch
如果有一个包含这些值的数组array(150,30,0),该怎么办? - Muhammad Raheel
1
@KingCrunch,询问是否有内置函数可以执行简单操作有什么问题吗?当我编写小型实用程序函数时,我经常会想到这个问题。 - Flash
好的,非常感谢大家给予的帮助。谢谢你们的建议! - Muhammad Raheel
1
我在搜索后尝试了一下,但没有找到任何东西,因此我问了一下,可能是我漏掉了什么。 - Muhammad Raheel
显示剩余3条评论
10个回答

10
你可以将输入的数组与排序后的数组进行比较,如果它们相等就可以了。
$input  = array(50, 100, 150);
$sorted = array_values($input);
sort($sorted);

if ( $input === $sorted ) {
  // input array was already sorted
}

5
function arraySorted($array) {
    $a = $array;
    $b = $array;
    sort($b);
    if ($a == $b){
        return true;
    } else {
        return false;
    }
}

//test for [0],[3],[2]
$input  = array(0 => 250,
                3 => 100,
                2 => 150);
var_dump($input);
echo "<br />";
//array(3) { [0]=> int(250) [3]=> int(100) [2]=> int(150) }

var_dump(arraySorted($input));
echo "<br />";
//bool(false) 

//test for [0],[1],[2]
$input  = array(0 => 250,
                1 => 100,
                2 => 150);
var_dump($input);
echo "<br />";
//array(3) { [0]=> int(250) [1]=> int(100) [2]=> int(150) }

var_dump(arraySorted($input));
echo "<br />";
//bool(false)

//test for [0],[3],[2] and asc values
$input  = array(0 => 50,
                1 => 100,
                2 => 150);
var_dump($input);
echo "<br />";
//array(3) { [0]=> int(50) [1]=> int(100) [2]=> int(150) }

var_dump(arraySorted($input));
echo "<br />";
//bool(true)

去掉我的-1,但我不喜欢它,我理解值已排序的排序数组,键不重要。对于这些情况,您的代码无法正常工作。但在原始问题中,这一点已经明确定义,所以没问题。只是想让您知道,在我看来,这个数组:array('one' => 50, 'two' => 100, 'three' => 150); 是有序的,但您的代码将返回false。 - jasir

2

由于PHP不知道数组是否已排序,它无法保留状态。唯一的解决方案是对数组进行迭代。


2

你可以使用array_reduce函数来比较每个元素与下一个元素是否有序,如果数组无序则会抛出异常。


1

这里,您可以尝试使用此代码:

<?php

$sort = array(
    0 => 50,
    1 => 100,
    2 => 150
);

$default = $sort;
sort($sort);

$flag = true;
foreach($sort as $key=>$value)
    if($value!=$default[$key])
        $flag = false;  

if($flag)
    echo "Already sorted";  
else
    echo "Not Already sorted";  
?>

8
那看起来可疑得像一个循环。 :) - Expedito

1

我很惊讶没有人提议实际检查输入数组本身。 也许这是我的C++背景,但我只关心算法的复杂度,坦率地说,复制和排序数组只是愚蠢的做法。

namespace Util\Functions;

function compare($lhs, $rhs, $descendingOrder = false)
{
    $result = 0;
    if ($lhs < $rhs) {
        $result = -1;
    } else if ($lhs > $rhs) {
        $result = 1;
    }

    if ($descendingOrder) {
        $result *= -1;
    }

    return $result;
}

function isSorted(array $arr, callable $compareFunction = null)
{
    $count = count($arr);
    if ($count < 2){ 
        return true;
    }
    if ($compareFunction === null) {
        $compareFunction = 'Util\Functions\compare';     
    }

    for ($i = 1; $i < $count; $i++) {
        if ($compareFunction($arr[$i - 1], $arr[$i]) > 0) {
            return false;
        }
    }

    return true;
}

顺便说一句,我知道 OP 不想用循环,但是因为没有好的解决方案,我决定发一个代码供任何人复制粘贴到他的项目中。


0

数组无法知道它们是否已排序,因为有许多排序方式。仅对于数字,可以是升序、降序、绝对升序、绝对降序等等。你明白了。然而,检查数组是否已排序的算法与排序顺序无关

接下来是isSorted函数,如果给定comparator,将检查数组元素是否按该顺序排序。这样,isSorted不知道正在测试哪个顺序,而是将其委托给comparator

由于问题显示数字按特定顺序排列,因此我还提供了基于php <的升序comparator

$xs = [
  50,
  100,
  150
];

// Here is example of comparator, it have to take 2 elements, and return boolean signaling weather relationship you want to test holds true
$comparator = function($current, $next) {
  return $current < $next;
};

function isSorted($xs, $comparator){

  $answer = true;
  foreach ($xs as $key => $current) {
    if(!isset($xs[$key + 1]))
        continue;

    $next = $xs[$key + 1];

    $answer = $answer && $comparator($current, $next);
  }

  return $answer;
}

0

这将在不考虑键名的情况下工作:

$a = array(5 => 'aple', 3 => 'banana', 1 =>'citron');
$b = array(2 => 'orange', 1 => 'wine', 5 => 'apple');

echo arraySorted($a) ? "sorted" : 'not';
echo "\n";
echo arraySorted($b) ? "sorted" : 'not';

function arraySorted($array) {
   $sorted = $vals = array_values($array);
   sort($sorted);
       return $sorted === $vals;
}

0

你可以将其与已排序的数组进行比较,或者如果数组来自数据库,你可以通过SQL查询使用order by来控制它,PHP中没有内置函数来检查这一点。


0

我看到很多答案都在执行完整的数组排序,然后比较整个原始数组和整个排序副本。当然,这并不像它本应该的那样高效。要检查数组是否已排序,您无需复制、变异或排序它——只需迭代它并随时比较即可。带有早期 break/return 的脚本将做到绝对最小的工作。

(我还看到一些答案调用了array_values(),但我无法理解重新索引的价值所在。)

例如:(真实和错误结果的演示

$array = [50, 50, 100, 175];  // no break

$last = reset($array);
$isSorted = true;
foreach ($array as $value) {
    if ($last > $value) {
        $isSorted = false;
        break;
    }
    $last = $value;
}
var_export($isSorted);  //true

只有在数组完全排序或最后一个元素未排序时,此操作才会完整运行您的数据。

但是,如果您关心数组是否已排序,您可能只需对其进行排序并继续使用脚本。

如果您需要执行超快速评估,因为您正在处理大量数据,则可能需要使用php之外的语言。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接