В php как работает функция usort()

Я просмотрел документацию по php, онлайн-учебники, и ни один из них не показал, как на самом деле работает usort. У меня есть пример, с которым я играл ниже.

$data = array(

    array('msg' => 'some text','month' => 11,'level' => 10),

    array('msg' => 'some text','month' => 5,'level' => 10),

    array('msg' => 'some text','month' => 8,'level' => 10),

    array('msg' => 'some text','month' => 12,'level' => 10),

    array('msg' => 'some text','month' => 2,'level' => 10),

    array('msg' => 'some text','month' => 3,'level' => 10),

    array('msg' => 'some text','month' => 4,'level' => 10),

    array('msg' => 'some text','month' => 7,'level' => 10),

    array('msg' => 'some text','month' => 10,'level' => 10),

    array('msg' => 'some text','month' => 1,'level' => 10),

    array('msg' => 'some text','month' => 6,'level' => 10),

    array('msg' => 'some text','month' => 9,'level' => 10)

);

Я хотел иметь возможность сортировать месяцы от 12 до 1 (поскольку они неорганизованы) с помощью некоторой помощи, это было решением

function cmp($a, $b)
{
    if ($a["month"] == $b["month"]) 
    {
       return 0;
    }
    return ($a["month"] < $b["month"]) ? -1 : 1;
}

usort($data, "cmp");

но я не понимаю, как функция cmp сортирует массив. я попытался распечатать каждую переменную $a и $b следующим образом:

function cmp($a, $b)
{
   echo "a: ".$a['month']."<br/>";
   echo " b: ".$b['month']."<br/>";
   echo "<br/><br/>";
}

и выход был

a: 3
b: 5

a: 9
b: 3

a: 3
b: 8

a: 6
b: 3

a: 3
b: 12

a: 1
b: 3

a: 3
b: 2

a: 10
b: 3

a: 3
b: 11

a: 7
b: 3

a: 4
b: 3

a: 12
b: 2

a: 5
b: 12

a: 12
b: 11

a: 8
b: 12

a: 5
b: 8

a: 2
b: 11

a: 6
b: 9

a: 7
b: 6

a: 6
b: 4

a: 10
b: 6

a: 1
b: 6

a: 9
b: 4

a: 7
b: 1

a: 10
b: 7

не имеет смысла, как работает сортировка и почему используется cmp($a, $b). я попытался распечатать все его процессы, как вы можете видеть, но не пришел к какому-либо решению, как все это работает.

Спасибо


person Exploit    schedule 10.12.2011    source источник
comment
ваша последняя функция ничего не возвращает.   -  person Your Common Sense    schedule 10.12.2011
comment
Вы хотите знать, как все это сочетается друг с другом, или алгоритм, который usort использует за кулисами?   -  person Corbin    schedule 10.12.2011
comment
@corbin, да, если это общедоступная информация.   -  person Exploit    schedule 10.12.2011
comment
@col вам нужно включить массивы в тест, который вы делаете.   -  person Exploit    schedule 10.12.2011
comment
Конечно, это общедоступная информация. В конце концов, вы можете скачать исходный код PHP :). Сейчас мне лень проверять себя, но я верю, что PaulPRO использует реализацию быстрой сортировки. Для получения более подробной информации прочтите исходный код PHP.   -  person Corbin    schedule 10.12.2011
comment
какие? какие тесты? ваша вторая функция cmp ничего не возвращает, значит, всегда возвращает 0. Запуск usort с ней не имеет смысла.   -  person Your Common Sense    schedule 10.12.2011
comment
@Col.Shrapnel, можете ли вы вставить весь код, который вы пытаетесь, чтобы я мог сказать вам, чего вам не хватает?   -  person Exploit    schedule 10.12.2011
comment
Я говорю о ВАШЕМ коде. Вставил уже в ВАШ вопрос. Видите ли вы второй вариант функции cmp в вашем коде?   -  person Your Common Sense    schedule 10.12.2011


Ответы (5)


Сама функция cmp не выполняет сортировку. Он просто сообщает usort, если значение меньше, равно или больше другого значения. Например. если $a = 5 и $b = 9, он вернет 1, чтобы указать, что значение в $b больше, чем в $a.

Сортировка производится по usort.

person halfdan    schedule 10.12.2011
comment
вау, то, что ты сказал, имело большой смысл. Я должен был это видеть. мне всегда нужно вводить два аргумента в функцию cmp? - person Exploit; 10.12.2011
comment
Да, функция сравнения всегда принимает два аргумента. - person halfdan; 10.12.2011
comment
Я думаю, что он вернет -1 (а не 1, как упомянул Халфдан), чтобы указать, что значение в $b больше, чем значение в $a. - person Sid; 13.12.2016

Обратный вызов, предоставляемый функциям сортировки в PHP, имеет три возвращаемых значения:

0:  both elements are the same
-1 (<0): the first element is smaller than the second
1 (>0):  the first element is greater

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

person knittl    schedule 10.12.2011
comment
+1 Это то, что я искал. В документах PHP говорится, что версии PHP ниже 7 имеют ограничения -2147483648 to 2147483647, но они не излагают это четко, как вы. Ваше объяснение сделало бы документацию намного понятнее! - person mrClean; 21.04.2017

usort() использует реализацию Quicksort для сортировки массива, она вызывает вашу функцию cmp столько раз, сколько необходимо для полной сортировки массива с использованием этого алгоритма.

person Paul    schedule 10.12.2011
comment
Usort использует сортировку подсчетом, а не быструю сортировку. Проверьте это ijest.info/docs /IJEST11-03-09-057.pdf. - person user1613360; 26.07.2014
comment
@ user1613360 Вы перепутали usort PHP с алгоритмом usort, упомянутым в этой статье. Usort в PHP реализован с помощью Quicksort. - person Paul; 28.07.2014
comment
Подробнее о сортировке в PHP можно узнать здесь, но да, как упоминалось, по умолчанию большинство сортировок в PHP используют Quicksort. Смотрите примечание по ссылке. - person aug; 27.11.2015

Как уже упоминалось, usort использует алгоритм Quicksort. Кстати, вам не нужно явно сравнивать две строки. Вы можете использовать методы сравнения строк PHP.

Функция, которую вы создали,

function cmp($a, $b)
{
    if ($a["month"] == $b["month"]) 
    {
       return 0;
    }
    return ($a["month"] < $b["month"]) ? -1 : 1;
}

может быть просто записано следующим образом

function compareMyStrings($a, $b){
    return strnatcmp($a["month"], $b["month"]);
}

Надеюсь это поможет!

person pat    schedule 08.11.2014

Это еще одно решение, которое я нашел

<?php 
$users = array( array( "peter", "male", "46"), 
                array( "hans", "male", "19"), 
                array( "john", "male", "30"), 
                array( "linda", "female", "54"), 
                array( "erika", "female", "79")); 
usort($users, "whatevername"); 
function whatevername($whatever1, $whatever2) 
{ 
    // $whatever1 and $whatever2 are items from the $user array. 
    // index [2] is the age. 
    // Check if $whatever1 is older than $whatever2. 
    // Return 1 tells usort to swap the positions. 
    return $whatever1[2] > $whatever2[2]; 
} 

echo("<pre>"); 
print_r($users); 
echo("</pre>"); 
?>
person Mahendra Jella    schedule 27.11.2014