PHP usort () порядок в случае равенства - PullRequest
6 голосов
/ 25 февраля 2012

В руководстве по PHP для usort () говорится:

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

Кроме того,

Был введен новый алгоритм сортировки. Функция cmp_function не сохраняет исходный порядок сравнения элементов как равный.

Тогда мой вопрос: что произойдет, если два элемента равны (например, пользовательская функция возвращает 0)? Я использую эту функцию, и, очевидно, одинаковые элементы расположены в отсортированном массиве случайным образом.

Ответы [ 5 ]

4 голосов
/ 01 декабря 2016

Будьте осторожны, чтобы не перепутать "undefined" и "random".

A random Реализация действительно должна каждый раз давать различный порядок.Это подразумевало бы наличие специального кода для перетасовки результатов, когда они оказались равными.Это сделало бы алгоритм более сложным и медленным, и редко было бы желательным результатом.

Что означает undefined , это противоположность: при разработке алгоритма не было предпринято абсолютно никаких мер для обеспечения предсказуемостистабильный порядок.Это означает, что результат может отличаться при каждом запуске, , если , что является побочным эффектом алгоритма для этих данных.

Вы можете видеть базовая реализация сортировки в исходном коде PHP .Он состоит из смеси «быстрой сортировки» («разделяй и властвуй») и сортировки вставками (более простой алгоритм, эффективный для коротких списков) с оптимизированными вручную процедурами для списков из 2, 3, 4 и 5 элементов.

Таким образом, точное поведение равных членов будет зависеть от таких факторов, как размер списка, откуда в списке появляются эти равные члены, сколько равных членов имеется в одном пакете и так далее.В некоторых ситуациях алгоритм увидит, что они идентичны, и не поменяет их местами (идеал, потому что подкачка требует времени);в других он не будет сравнивать их напрямую, пока они не будут перемещены относительно других вещей, поэтому они окажутся в другом порядке.

1 голос
/ 19 декабря 2017

Я также нахожу то же самое, в то время как sorting my array, затем я нашел какую-то пользовательскую функцию, потому что php имеет некоторые ограничения для использования определенной sorting функции.

http://php.net/manual/en/function.uasort.php#Vd114535

PHP 7 использует алгоритм стабильной сортировки для небольших массивов (<16), но для больших массивов алгоритм все еще не стабилен. Кроме того, PHP не гарантирует, является ли сортировка с помощью * sort () стабильный или нет <a href="https://bugs.php.net/bug.php?id=53341" rel="nofollow noreferrer">https://bugs.php.net/bug.php?id=53341.

0 голосов
/ 29 апреля 2019

Я также столкнулся с той же проблемой, когда 2 строки имеют одинаковые значения, и когда применяется функция сортировки, меняется ее порядок, который я не хотел. Я хочу отсортировать ключи на основе их значений, если они равны, не меняйте порядок. Так вот мое решение -

// sample array 
$arr = Array("a" => 0.57,"b" => 1.19,"c" => 0.57,"d" => 0.57,"e" => 0.57,"f" => 0.57,"g" => 0.57,"h" => 0.57,"i" => 0.99,"j" => 1.19,"k" => 1.19);
    $multi_arr = [];
    foreach ($arr as $k=>$val){
       $multi_arr["$val"][] = array($k=>$val); 
    }
    uksort($multi_arr, function ($a, $b) { 
                    return $b > $a ? 1 : -1;
            });
    $s_arr = [];
    foreach ($multi_arr as $k=>$val){
        foreach($val as $p_id){         
            $p_arr = array_keys($p_id);
            $s_arr[] = $p_arr[0]; 
        }
    }
print_r($s_arr);

выход-

Array ([0] => b, [1] => j, [2] => k, [3] => i, [4] => a, [5] => c, [6] => d, [7] => e, [8] => f, [9] => g, [10] => h)

0 голосов
/ 01 декабря 2016

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

Пример:

$temp=array("b"=>"10","c"=>"10","d"=>"10","e"=>"4");

, так как указанный выше массив имеет длину 4 массивав которой 3 имеют те же значения, что и показанные b, c, d = 10;arsort() // Функция arsort () сортирует ассоциативный массив в порядке убывания, согласно значению

, если print_r(arsort($temp)) o / p: => Array ( [b] => 10 [c] => 10 [d] => 10 [e] => 4 )

, это означает, чтоВозвращает массив после сортировки равных значений, но сохраняет позицию (порядок) одинаковыми для равных значений

, но

, если $temp=array("a"=>"4",b"=>"10","c"=>"10","d"=>"10","e"=>"4"); здесь в вышеуказанном массиве b, c, d = 10 ограничены двумя крайнимилевый и правый массивы, имеющие значения, меньшие, чем значения в центре (b, c, d = 10)

arsort выше temp равен o / p: Array ( [c] => 10 [b] => 10 [d] => 10 [a] => 4 [e] => 4 )

это дает среднюю часть, т.е.[c] массив в центре.это означает, что если массив с одинаковыми значениями или равными значениями ограничен с обеих сторон массивом более низких значений, или первое значение меньше, чем порядок равенства, то среднее из трех значений массива будет первым, как первое из этих трех.

0 голосов
/ 25 февраля 2012

Если бы у меня был массив: ['b', 'a', 'c', 'b'], и я должен был отсортировать это, я бы получил: ['a','b','b','c'].Поскольку 'b' == 'b' php не может гарантировать, что один предшествует другому, поэтому порядок сортировки 'неопределен', однако, поскольку они равны, имеет ли это значение?

Если вы используете функцию сортировки, которая возвращает 0неравные объекты, с которыми вы сталкиваетесь с другой проблемой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...