2012-06-29 2 views
1

Я пытаюсь понять, как работает функция php usort. У меня есть такой код:Как понять логику usort?

<?php 
$users[] = array('login' => 'moon', 'name' => 'Chris'); 
$users[] = array('login' => 'star', 'name' => 'Piter'); 
$users[] = array('login' => 'mars', 'name' => 'Tim'); 
$users[] = array('login' => 'earth', 'name' => 'Garry'); 

function compare($a, $b) {     
    echo $a['login'] . '--' . $b['login'] . '<br />'; 
    echo strcmp($a['login'], $b['login']) . '<br />'; 
    return strcmp($a['login'], $b['login']);    
} 
usort($users, "compare"); 

echo '<pre>'; print_r($users); echo '</pre>'; 
?> 

Он выведет такой результат:

star--moon 
1 
star--mars 
1 
earth--star 
-1 
moon--earth 
1 
mars--moon 
-1 
earth--mars 
-1 
Array 
(
    [0] => Array 
     (
      [login] => earth 
      [name] => Garry 
     ) 

    [1] => Array 
     (
      [login] => mars 
      [name] => Tim 
     ) 

    [2] => Array 
     (
      [login] => moon 
      [name] => Chris 
     ) 

    [3] => Array 
     (
      [login] => star 
      [name] => Piter 
     ) 

) 

Насколько я понимаю, вторые пары должны быть функцией сравнения, и он может возвращать только 3 значения (-1,0, 1) и usort используйте этот результат, чтобы отсортировать массив? Также я прочитал: usort использует реализацию Quicksort для сортировки массива. Вот почему звезда первая и moon - секунда? Быстрое разделение массива на две части, а затем сортировку? И могу ли я реализовать эту функцию для массива 2,3 измерений?

ответ

2

Да, usort использует функцию сравнения, чтобы сравнить значения и отсортировать массив с помощью алгоритма quicksort. От http://php.net/manual/en/function.usort.php:

Функция сравнения должна возвращать целое число меньше, равно или больше нуля, если первый аргумент считается соответственно, меньше, равна или больше, чем второй.

Ссылки на реализацию usort в PHP можно найти здесь: What sort algorithm does PHP use?. Согласно http://murilo.wordpress.com/2011/02/05/phps-sort-functions-are-bad-designed/ алгоритм использует средний элемент как элемент поворота, реализованный как это:

offset = (end - begin) >> 1; 

Это должно быть, почему алгоритм использует «звезда» в качестве первого элемента поворота.

Для многомерных массивов используйте uasort, если вы хотите поддерживать ассоциацию индексов. This question содержит пример сортировки многомерных массивов.

+0

Отличный ответ. Но вы можете объяснить один момент. В статье на ваш ответ написано, что лучше использовать 'shuffle' перед сортировкой. Этот «shuffle» не влияет на элемент поворота? Это функция алгоритма, что лучше работать с перетасованными массивами? –

+0

Да, перетасовка массива перед сортировкой может избежать сценариев наихудшего сценария, например, когда массив уже отсортирован, но алгоритм по-прежнему выбирает средний элемент как элемент поворота. Но этот средний элемент, вероятно, является другим элементом после перетасовки массива, чем до тасования. –

1

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

+0

И как он определяет, какие элементы он должен сравнивать во время следующей итерации? И, также, он должен сравнивать каждый элемент друг с другом? –

+0

Прочитайте комментарии на http://php.net/manual/en/function.usort.php - в частности, первый. Он не сравнивает каждый элемент с любым другим элементом - алгоритм сортировки не нужен. –

Смежные вопросы