PHP – Множество функций uasort разбивает сортировку

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

Array ( id93294 => (array ( Name => "Tom Anderson", Birthday => "03/17/1975"), id29349 => (array ( Name => "Tom Anderson", Birthday => "03/17/1975") ) 

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

Как сортировать несколько раз, не испорчая мои предыдущие сортировки.

PS Я использую uasort.

Solutions Collecting From Web of "PHP – Множество функций uasort разбивает сортировку"

Обновить

Недавно я ответил на этот вопрос гораздо более способным образом в «окончательной» теме по сортировке многомерных массивов. Вы можете спокойно прочесть оставшуюся часть этого ответа и сразу перейти по ссылке для более эффективного решения.

Оригинальный ответ

Функция uasort позволяет вам определить свою собственную функцию сравнения. Просто поставьте все критерии, которые вы хотите в этом.

Например, сортировать по дням рождения, а затем по имени:

 function comparer($first, $second) { // First see if birthdays differ if ($first['birthday'] < $second['birthday']) { return -1; } else if ($first['birthday'] > $second['birthday']) { return 1; } // OK, birthdays are equal. What else? if ($first['name'] < $second['name']) { return -1; } else if ($first['name'] > $second['name']) { return 1; } // No more sort criteria. The two elements are equal. return 0; } 

Я игнорирую тот факт, что в вашем примере дни рождения не в формате, который можно упорядочить простым сравнением с помощью оператора < . На практике вы сначала конвертировали их в тривиально сопоставимый формат.

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

Я буду предполагать PHP 5.3 для следующего примера, чтобы использовать удобный синтаксис функции anon. Но в принципе, вы можете сделать то же самое с create_function .

 function make_comparer() { $criteriaNames = func_get_args(); $comparer = function($first, $second) use ($criteriaNames) { // Do we have anything to compare? while(!empty($criteriaNames)) { // What will we compare now? $criterion = array_shift($criteriaNames); // Do the actual comparison if ($first[$criterion] < $second[$criterion]) { return -1; } else if ($first[$criterion] > $second[$criterion]) { return 1; } } // Nothing more to compare with, so $first == $second return 0; }; return $comparer; } 

Тогда вы можете:

 uasort($myArray, make_comparer('birthday', 'name')); 

Этот пример, возможно, пытается быть слишком умным; в общем, я не люблю использовать функции, которые не принимают их аргументы по имени. Но в этом случае сценарий использования – очень сильный аргумент в пользу того, что он слишком умный.

Отличный вопрос.

Этот псевдокод исходит из определения проблемы, которую вы дали, и предназначен для функции обратного вызова, заданной для uasort . Я не могу заполнить детали, потому что вы опустили код, который используете; надеюсь, это приведет вас к правильному пути.

 function compare(p1, p2): if birthdays of p1 and p2 are not the same compare by birthday else compare by hometown 

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