我正在使用usort对每个元素中的关联数组进行排序.
当我在数组中排序的所有值都相同时,它仍然会改变数组中元素的位置,有没有办法防止这种情况?
例如:
array(
array('name' => 'Ben', 'authn_weight' => 85.3),
array('name' => 'Josh', 'authn_weight' => 85.3),
array('name' => 'Fred', 'authn_weight' => 85.3)
);
Run Code Online (Sandbox Code Playgroud)
可以改为:
array(
array('name' => 'Josh', 'authn_weight' => 85.3),
array('name' => 'Ben', 'authn_weight' => 85.3),
array('name' => 'Fred', 'authn_weight' => 85.3)
);
Run Code Online (Sandbox Code Playgroud)
这是排序功能:
private function weightSortImplementation($a, $b){
$aWeight = $a['autn_weight'];
$bWeight = $b['autn_weight'];
if ($aWeight == $bWeight) {
return 0;
}
return ($aWeight < $bWeight) ? 1 : -1;
}
Run Code Online (Sandbox Code Playgroud)
我已经检查过该weightSortImplementation
函数总是返回0表示它们是相同的.那为什么这仍然重新排序阵列?
Ja͢*_*͢ck 12
Aha,Schwartzian变换的一个案例.
它基本上包括三个步骤:
这是(我已经将它调整到您的特定用例):
function decorate(&$v, $k)
{
$v['authn_weight'] = array($v['authn_weight'], $k);
}
function undecorate(&$v, $k)
{
$v['authn_weight'] = $v['authn_weight'][0];
}
array_walk($a, 'decorate');
usort($a, 'weightSortImplementation');
array_walk($a, 'undecorate');
Run Code Online (Sandbox Code Playgroud)
诀窍在于以下断言:
array($x, 0) < array($x, 1)
Run Code Online (Sandbox Code Playgroud)
这是保持数组正确顺序的原因.并且,不需要递归:)
从文档:
如果两个成员比较相等,则它们在排序数组中的相对顺序是未定义的.
您可以使用此函数[source]在两个元素相等的情况下保留顺序:
function mergesort(&$array, $cmp_function = 'strcmp') {
// Arrays of size < 2 require no action.
if (count($array) < 2) return;
// Split the array in half
$halfway = count($array) / 2;
$array1 = array_slice($array, 0, $halfway);
$array2 = array_slice($array, $halfway);
// Recurse to sort the two halves
mergesort($array1, $cmp_function);
mergesort($array2, $cmp_function);
// If all of $array1 is <= all of $array2, just append them.
if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {
$array = array_merge($array1, $array2);
return;
}
// Merge the two sorted arrays into a single sorted array
$array = array();
$ptr1 = $ptr2 = 0;
while ($ptr1 < count($array1) && $ptr2 < count($array2)) {
if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {
$array[] = $array1[$ptr1++];
}
else {
$array[] = $array2[$ptr2++];
}
}
// Merge the remainder
while ($ptr1 < count($array1)) $array[] = $array1[$ptr1++];
while ($ptr2 < count($array2)) $array[] = $array2[$ptr2++];
return;
}
Run Code Online (Sandbox Code Playgroud)