PHP';s USORT回调函数参数

PHP';s USORT回调函数参数,php,usort,Php,Usort,这是一个非常深奥的问题,但我真的很好奇。今天,我是多年来第一次使用usort,我对到底发生了什么特别感兴趣。假设我有以下数组: $myArray = array(1, 9, 18, 12, 56); 我可以用usort进行分类: usort($myArray, function($a, $b){ if ($a == $b) return 0; return ($a < $b) ? -1 : 1; }); 并运行以下命令: usort($myArray, function($a,

这是一个非常深奥的问题,但我真的很好奇。今天,我是多年来第一次使用usort,我对到底发生了什么特别感兴趣。假设我有以下数组:

$myArray = array(1, 9, 18, 12, 56);
我可以用usort进行分类:

usort($myArray, function($a, $b){
  if ($a == $b) return 0;
  return ($a < $b) ? -1 : 1;
});
并运行以下命令:

usort($myArray, function($a, $b){
  return strcmp($a[0], $b[0]);
});
这将根据[0]索引值按字母顺序对我的子数组进行排序。但这并没有提供任何关于a美元和b美元是什么的清晰信息。我只知道匹配的模式,我正在寻找


有人能提供一些关于实际发生的事情的清晰信息吗?

要对任何事情进行排序,您需要一种方法来比较两个项目,并确定一个项目是否在另一个项目之前。这是你们提供给我们的。此函数将从输入数组中传递两个项,并返回它们应按的顺序

一旦有了比较两个元素的方法,就可以使用自己选择的排序算法

如果您不熟悉,您可能想看看像这样一个简单的朴素算法是如何使用比较函数的


在幕后,PHP使用的是a。

对$a和$b的精确定义将取决于用于对数组进行排序的算法。要对任何内容进行排序,必须有一种方法来比较两个元素,这就是回调函数的用途。一些排序算法可以从数组中的任何位置开始,其他排序算法只能从数组的特定部分开始,因此$a和$b中没有固定的含义,只是它们是数组中必须根据当前算法进行比较的两个元素

此方法可用于阐明PHP使用的算法

<?php

$myArray = array(1, 19, 18, 12, 56);

function compare($a, $b) {
    echo "Comparing $a to $b\n";
    if ($a == $b) return 0;
    return ($a < $b) ? -1 : 1;
}

usort($myArray,"compare");
print_r($myArray);
?>
从输出和查看源代码,我们可以看到所使用的排序确实是一个实现,请检查PHP源代码中的(链接到的版本有点旧,但没有太大变化)

它选择数组中间的支点,在这种情况下,18,然后需要重新排序列表,以便所有小于(比使用的比较函数)在枢轴之前的元素都在枢轴之前,从而大于枢轴的所有元素都跟随它,我们可以看到它这样做,当它把所有的东西都和最初的18个相比较时

进一步的图解说明

Step 0: (1,19,18,12,56); //Pivot: 18, Step 1: (1,12,18,19,56); //After the first reordering Step 2a: (1,12); //Recursively do the same with the lesser, here //pivot's 12, and that's what it compares next if //you check the output. Step 2b: (19,56); //and do the same with the greater 步骤0:(1,19,18,12,56)//支点:18, 步骤1:(1,12,18,19,56)//在第一次重新排序之后 步骤2a:(1,12)//在这里,递归地对较小的进行相同的操作 //pivot是12,如果 //检查输出。 步骤2b:(19,56)//对更大的 usort()或uasort()在排序结果上有一个人类感觉错误。请参见代码段:

function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; }
$x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38);
uasort($x,'xxx');
print_r($x);
你看到虫子了吗?不好的,让我解释一下。 最初的三个“9”元素按关键顺序排列:2、3、4。但在结果中,三个“9”元素现在按键顺序排列:4、3、2,即等值元素在排序后按相反的键顺序排列

如果元素只有一个值,如上面的示例中所示,我们可以使用它。然而,如果元素是复合值,那么它可能会导致人情错误。请参阅另一个代码段。我们将对多个点进行水平排序,即根据x坐标值的升序进行排序:

function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; }
$x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'),
       3=>array('x'=>9,  'v'=>'Lara'),4=>array('x'=>9,  'v'=>'Croft'),
       5=>array('x'=>15,  'v'=>'and'),6=>array('x'=>38,  'v'=>'Tombraider'));
uasort($x,'xxx');
print_r($x);
你看,“我爱劳拉·克罗夫特和汤姆布雷德”变成了“我爱劳拉和汤姆布雷德”


我称之为“人情bug”
,因为这取决于你使用什么案例,以及当比较值相同时,你觉得在现实世界中应该如何排序。

我相信乔纳森对“幕后”部分很感兴趣。回答很好。保罗的建议足够了,而且是第一个。因此我答应了他。不过,我对你的建议投了更高的票,我很欣赏你的彻底性。为了论证起见,我建议第一个并不总是更好。如果第二个答案更完整,那么花时间完整回答问题的人应该得到奖励。
function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; }
$x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38);
uasort($x,'xxx');
print_r($x);
Array ( [5] => 6 [4] => 9 [3] => 9 [2] => 9 [1] => 10 [6] => 38 )
function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; }
$x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'),
       3=>array('x'=>9,  'v'=>'Lara'),4=>array('x'=>9,  'v'=>'Croft'),
       5=>array('x'=>15,  'v'=>'and'),6=>array('x'=>38,  'v'=>'Tombraider'));
uasort($x,'xxx');
print_r($x);
Array ( [1] => Array ( [x] => 1 [v] => l ) [4] => Array ( [x] => 9 [v] => croft ) 
             [3] => Array ( [x] => 9 [v] => Lara ) [2] => Array ( [x] => 9 [v] => love )
             [5] => Array ( [x] => 15 [v] => and ) [6] => Array ( [x] => 38 [v] => Tombraider ) )