我试图了解在使用usort()
时,数组中的项是如何传递给我的值比较函数的。每次迭代的$x
和$y
值的打印输出如下:
迭代1:
// $x
array(2) { ["k1"]=> int(21) ["k2"]=> string(1) "e" }
// $y
array(2) { ["k1"]=> int(920) ["k2"]=> string(1) "z" }
迭代2:
// $x
array(2) { ["k1"]=> int(842) ["k2"]=> string(1) "t" }
// $y
array(2) { ["k1"]=> int(21) ["k2"]=> string(1) "e" }
迭代3:
// $x
array(2) { ["k1"]=> int(920) ["k2"]=> string(1) "z" }
// $y
array(2) { ["k1"]=> int(21) ["k2"]=> string(1) "e" }
迭代4:
// $x
array(2) { ["k1"]=> int(842) ["k2"]=> string(1) "t" }
// $y
array(2) { ["k1"]=> int(920) ["k2"]=> string(1) "z" }
我的数据:
$data = array(
array( 'k1' => 920, 'k2' => 'z' ),
array( 'k1' => 21, 'k2' => 'e' ),
array( 'k1' => 842, 'k2' => 't' )
);
我的自定义功能:
function value_compare_func( $x, $y ) {
if ( $x['k1'] > $y['k1'] ) {
return true;
} elseif ( $x['k1'] < $y['k1'] ) {
return false;
} else {
return 0;
}
}
排序数组:
usort( $data, 'value_compare_function' );
对于第一次迭代,$x['k1']
是$data[1]['k1']
,$y['k1']
是$data[0][k1]
。为什么我的$data
数组中的项没有按顺序传递给value_compare_func()
?例如,在第一次迭代中,我希望$x['k1']
是$data[0]['k1']
,$y['k1']
是$data[1]['k1']
,但事实并非如此。
如何将这些项传递给比较函数需要了解快速排序算法。其要点是,数组中的某个元素被指定为轴心(实际上它可以是任何元素,但在有效的实现中,它通常是中值元素),然后在轴心的两侧进行比较以对数组进行排序。
这基本上是usort
在PHP中的底层实现。
因此,试图观察元素传递给比较函数的顺序是相对无用的。顺序完全不重要。重要的是,您可以放心,它们将始终根据回调函数返回的内容进行正确排序。
这里需要注意的重要一点是,手册明确警告不要因为特定原因从回调返回非整数的值(它们将被强制转换为整数),在您的示例中,您将从回调返回一个布尔false
,当强制转换为integer
时,它将变为0
。由于0
表示两个值相等,因此您不会也不应该在此处期望一个正确排序的数组。
始终确保在回调中返回$a > $b
时的整数值1
,在$a < $b
时的整值-1
,以及在$a == $b
时的整数0
compare函数应该返回一个数值。由于返回布尔值,因此比较将变为不可预测的false == 0
,因此在排序中会丢失两者之间的区别。
您应该更改您的代码如下:
function value_compare_func( $x, $y ) {
if ( $x['k1'] > $y['k1'] ) {
return 1;
} elseif ( $x['k1'] < $y['k1'] ) {
return -1;
} else {
return 0;
}
}
并且结果将更加合乎逻辑。