PHP usort()命令在相等的情况下

时间:2012-02-24 21:38:25

标签: php sorting

在PHP manual for usort()中,它声明:

  

如果两个成员比较相等,则它们在排序数组中的相对顺序是未定义的。

此外,

  

引入了一种新的排序算法。 cmp_function不保持元素比较的原始顺序相等。

然后我的问题是:如果两个元素相等会发生什么(例如用户定义的函数返回0)? 我正在使用这个函数,显然相等的项目在排序的数组中随机排列。

5 个答案:

答案 0 :(得分:4)

小心不要混淆" undefined"和"随机"。

随机实现确实会每次都给出不同的顺序。这意味着当他们发现结果相等时,会有特定的代码来重新调整结果。这将使算法更复杂和更慢,并且很少是理想的结果。

undefined 意味着相反:在设计算法以获得可预测或稳定的顺序时,绝对不小心。这意味着每次运行时可能的结果不同, if 恰好是算法对该数据的副作用。

您可以看到the core sort implementation in the PHP source code。它由"快速排序"的混合物组成。 (划分和征服)和插入排序(一种对短列表有效的简单算法),手动优化的例程用于2,3,4和5个元素的列表。

因此,平等成员的确切行为将取决于诸如列表大小,列表中相等成员来的位置,一批中有多少相等成员等因素。在某些情况下,算法会看到它们是相同的,而不是交换它们(理想的,因为交换需要时间);在其他情况下,它不会直接比较它们,直到它们已经相对于其他事物被移动,因此它们将以不同的顺序结束。

答案 1 :(得分:1)

我在sorting我的array时也发现了相同的内容,然后我发现了一些自定义函数,因为php对使用定义的sorting函数有一些限制。

http://php.net/manual/en/function.uasort.php#Vd114535

  

PHP 7对小型数组使用稳定的排序算法(< 16),   但对于较大的阵列,算法仍然不稳定。   此外,PHP不保证是否使用* sort()进行排序   稳定与否https://bugs.php.net/bug.php?id=53341

答案 2 :(得分:0)

如果我有一个数组:['b', 'a', 'c', 'b']而且我要对此进行排序,我会得到:['a','b','b','c']。由于'b' == 'b' php不能保证一个在另一个之前,所以排序顺序是'undefined',但是因为它们是相同的,这有关系吗?

如果您使用的sort函数对于不相等的对象返回0,那么您将面临完全不同的问题。

答案 3 :(得分:0)

我也面临着同样的问题,其中2行具有相同的值,并且当应用sort函数时,它的顺序被更改了,这是我不想要的。我想根据它们的值对键进行排序,如果它们相等,请不要更改顺序。所以这是我的解决方案-

// sample array 
$arr = Array("a" => 0.57,"b" => 1.19,"c" => 0.57,"d" => 0.57,"e" => 0.57,"f" => 0.57,"g" => 0.57,"h" => 0.57,"i" => 0.99,"j" => 1.19,"k" => 1.19);
    $multi_arr = [];
    foreach ($arr as $k=>$val){
       $multi_arr["$val"][] = array($k=>$val); 
    }
    uksort($multi_arr, function ($a, $b) { 
                    return $b > $a ? 1 : -1;
            });
    $s_arr = [];
    foreach ($multi_arr as $k=>$val){
        foreach($val as $p_id){         
            $p_arr = array_keys($p_id);
            $s_arr[] = $p_arr[0]; 
        }
    }
print_r($s_arr);

输出-

  

Array([0] => b,[1] => j,[2] => k,[3] => i,[4] => a,[5] => c,[6] => d,[7] => e,[8] => f,[9] => g,[10] => h)

答案 4 :(得分:-1)

了解如果所有比较值相同,php不关心顺序。

示例:

$temp=array("b"=>"10","c"=>"10","d"=>"10","e"=>"4");

如上所述阵列具有4个阵列长度,其中3个具有与所示的相同的值b,c,d = 10; arsort() // arsort()函数根据值

按降序对关联数组进行排序

如果print_r(arsort($temp)) o / p:=> Array ( [b] => 10 [c] => 10 [d] => 10 [e] => 4 )

这意味着它在排序相等值后返回数组,但保持位置(顺序)相同以获得相等的值

但是

如果$temp=array("a"=>"4",b"=>"10","c"=>"10","d"=>"10","e"=>"4");  在上面的数组b中,c,d = 10位于两个极端左右阵列下,其值小于中心(b,c,d = 10)值

以上温度的arsort是o / p: Array ( [c] => 10 [b] => 10 [d] => 10 [a] => 4 [e] => 4 )

它给中间部分,即[c]数组在中心。 这意味着如果相似值或相等值数组从两侧由较低值数组限制或第一个值较低,那么等于的顺序从三个数组值中给出中间一个作为第一个中的第一个。