Это действительно эзотерический вопрос, но мне действительно интересно. Я использую usort впервые за многие годы, и меня особенно интересует, что именно происходит. Предположим, у меня есть следующий массив:
$myArray = array(1, 9, 18, 12, 56);
Я мог бы сортировать это с помощью usort:
usort($myArray, function($a, $b){ if ($a == $b) return 0; return ($a < $b) ? -1 : 1; });
Я не на 100% понимаю, что происходит с двумя параметрами $ a и $ b. Каковы они и что они представляют. Я имею в виду, я мог предположить, что $ a представляет текущий элемент в массиве, но что именно происходит с этим? Что такое $ b?
Я мог бы увеличить свой массив, чтобы включить строки:
$myArray = array( array("Apples", 10), array("Oranges", 12), array("Strawberries", 3) );
И запустите следующее:
usort($myArray, function($a, $b){ return strcmp($a[0], $b[0]); });
И это будет сортировать мои дочерние массивы в алфавитном порядке на основе значения индекса [0]. Но это не дает никакой ясности в отношении того, что такое $ a и $ b. Я знаю только, что соответствие шаблону я ищу.
Может ли кто-нибудь дать некоторую ясность относительно того, что на самом деле происходит?
Чтобы отсортировать все, что вам нужно, это средство для сравнения двух предметов и выяснить, идет ли речь о другом. Это то, что вы предлагаете. Эта функция будет передана двумя элементами из вашего входного массива и возвращает порядок, в котором они должны быть.
Когда у вас есть средство для сравнения двух элементов, вы можете использовать алгоритм сортировки по вашему выбору .
Если вы незнакомы, вам может понравиться, как простой наивный алгоритм, такой как bubblesort, будет использовать функцию сравнения.
PHP- скрипт, использующий quicksort , находится за кулисами.
Точное определение $ a и $ b будет зависеть от алгоритма, используемого для сортировки массива. Чтобы отсортировать все, что у вас есть, чтобы сравнить два элемента, это то, для чего используется функция обратного вызова. Некоторые алгоритмы сортировки могут начинаться в любом месте массива, другие могут начинаться только в определенной его части, поэтому в $ a и $ b нет фиксированного значения, кроме двух элементов в массиве, которые нужно сравнивать в соответствии с текущим алгоритмом ,
Этот метод можно использовать для пролить свет на используемый алгоритм PHP.
<?php $myArray = array(1, 19, 18, 12, 56); function compare($a, $b) { echo "Comparing $a to $b\n"; if ($a == $b) return 0; return ($a < $b) ? -1 : 1; } usort($myArray,"compare"); print_r($myArray); ?>
Вывод
vinko@mithril:~$ php sort.php Comparing 18 to 19 Comparing 56 to 18 Comparing 12 to 18 Comparing 1 to 18 Comparing 12 to 1 Comparing 56 to 19 Array ( [0] => 1 [1] => 12 [2] => 18 [3] => 19 [4] => 56 )
Из вывода и просмотра источника мы видим, что используемая сортировка действительно представляет собой быструю сортировку , проверьте Zend / zend_qsort.c в источнике PHP (связанная с версией немного устаревшая, но не сильно изменившаяся).
Он выбирает стержень в середине массива, в этом случае 18, тогда ему необходимо изменить порядок списка, чтобы все элементы, которые меньше (в зависимости от используемой функции сравнения), чем точка поворота, приходили перед стержнем и так, чтобы все элементы, которые больше, чем точка поворота, после этого, мы можем видеть, что это делает это, когда сначала сравнивает все с 18.
Еще одно схематическое объяснение.
Стади 0: (1,19,18,12,56); // Сводка: 18, Стадия 1: (1,12,18,19,56); // После первого переупорядочения Стади 2а: (1,12); // Рекурсивно делать то же самое с меньшим, здесь // pivot's 12, и вот что он сравнивает следующим образом, если // вы проверяете вывод. Стади 2b: (19,56); // и делаем то же самое с большим
usort () или uasort () имеют ошибку, связанную с человеком, для сортированного результата. Смотрите сегмент кода:
function xxx($a,$b) { if ($a==$b) return 0; else return $a<$b?-1:1; } $x=array(1=>10,2=>9,3=>9,4=>9,5=>6,6=>38); uasort($x,'xxx'); print_r($x);
результат:
Array ( [5] => 6 [4] => 9 [3] => 9 [2] => 9 [1] => 10 [6] => 38 )
Вы видите ошибку? Нет? Хорошо, позвольте мне объяснить это. Исходные три «9» эльмента находятся в ключевом порядке: 2,3,4. Но в результате три «9» элемента теперь находятся в ключевом порядке: 4,3,2, т.е. элементы с равным значением находятся в обратном ключевом порядке после сортировки.
Если элемент является единственным значением, как в приведенном выше примере, с нами все в порядке. Однако, если элемент является составной величиной, то это может вызвать ошибку в отношении человека. См. Другие сегменты кода. Мы должны сортировать много точек по горизонтали, т. Е. Сортировать их на основе возрастающего x-координатного порядка значений:
function xxx($a,$b) { if ($a['x']==$b['x']) return 0; else return $a['x']<$b['x']?-1:1; } $x=array(1=>array('x'=>1, 'v'=>'l'),2=>array('x'=>9, 'v'=>'love'), 3=>array('x'=>9, 'v'=>'Lara'),4=>array('x'=>9, 'v'=>'Croft'), 5=>array('x'=>15, 'v'=>'and'),6=>array('x'=>38, 'v'=>'Tombraider')); uasort($x,'xxx'); print_r($x);
результат:
Array ( [1] => Array ( [x] => 1 [v] => l ) [4] => Array ( [x] => 9 [v] => croft ) [3] => Array ( [x] => 9 [v] => Lara ) [2] => Array ( [x] => 9 [v] => love ) [5] => Array ( [x] => 15 [v] => and ) [6] => Array ( [x] => 38 [v] => Tombraider ) )
Вы видите: « Я люблю Лару Крофт и Тимбрайдер », становится « Я люблю Крови Лару и Tombraider ».
Я называю это ошибкой для человека, потому что это зависит от того, какой случай вы используете, и как вы чувствуете, что его нужно сортировать в реальном мире, когда сравниваемые значения одинаковы.