当我在数组中排序的所有值是相同的,然后它仍然会改变数组中元素的位置,是否有一种方法可以防止这种情况?

问题描述 投票:0回答:2

array( array('name' => 'Josh', 'authn_weight' => 85.3), array('name' => 'Ben', 'authn_weight' => 85.3), array('name' => 'Fred', 'authn_weight' => 85.3) );

这是排序函数:

private function weightSortImplementation($a, $b){ $aWeight = $a['autn_weight']; $bWeight = $b['autn_weight']; if ($aWeight == $bWeight) { return 0; } return ($aWeight < $bWeight) ? 1 : -1; }

我已经检查了
weightSortImplementation
函数始终返回0,显示它们是相同的。那么,为什么这仍然重新排序数组?

aha,
SchwartzianTransform的一个案例。

基本上包括三个步骤:

任命;您将每个值变成一个数组,其中值为第一个元素,而键/索引则将其作为第二个元素

(按照正常)

股票;您反向步骤1

php arrays sorting usort stable-sort
2个回答
13
投票
在这里(我已经将其调整为您的特定用例):

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'); trick在以下断言中:

array($x, 0) < array($x, 1)

    这是保持数组正确顺序的原因。而且,无需递归:)
  1. 文档:

如果两个成员将其相等,则它们在排序阵列中的相对顺序不确定。


您可以使用此函数

[源]

在两个元素相等的情况下,可以保留顺序:
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;
} 


9
投票
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.