usort изменяет порядок массива

У меня есть функция usort с одной строкой: вернуть 0.
Я пытался использовать его на массиве объектов stdClass, и это меняет
их порядок, как это возможно?

3 ответа

Решение

Предполагаемое свойство называется стабильностью: алгоритм стабильной сортировки не изменит порядок элементов, которые равны.

Функции сортировки в php нестабильны (потому что нестабильные сортировки могут быть немного быстрее). Из документации usort:

Если два члена сравниваются как равные, их порядок в отсортированном массиве не определен.

Если вам нужен стабильный алгоритм сортировки, вы должны реализовать его самостоятельно.

Если вы ищете быстрое решение для стабильной usortВы могли бы использовать uksort как в следующем примере:

<?php

uksort($array, function ($ak, $bk) use ($array) {
    $a = $array[$ak];
    $b = $array[$bk];

    if ($a['foo'] === $b['foo']) 
        return $ak - $bk;

    return $a['foo'] > $b['foo'] ? 1 : -1;
});

Это работает, как ожидается, только если начальные индексы (ключи) $array в порядке возрастания.

Это потому, что эта функция означает: "Мне действительно все равно, как они отсортированы, они равны мне". С этим простым примером я получаю обратный массив:

function sortaaa($a,$b) {return 0;}
$array = array(1,2,3,4,5);
usort($array,"sortaaa");
var_dump($array);
//prints array(5) { [0]=> int(5) [1]=> int(4) [2]=> int(3) [3]=> int(2) [4]=> int(1) }

Так что, похоже, PHP зацикливает массив в обратном порядке в функции usort, Итак, обратите внимание на usort Руководство утверждает, что

Если два члена сравниваются как равные, их порядок в отсортированном массиве не определен.

Другие вопросы по тегам