Практически перед каждым PHP-программистом становится задача отсортировать многомерный массив. К примеру вот такой вот:
|
По, допустим, ключу year, как же сделать это грамотно?
Классическое решение
Естественно первое про что вы подумали, это сортировка многомерного массива с помощью uasort, да? Набросаем вот такой вот код:
|
Запускаем, и засекаем время выполнения… Итого: 13.15 сек. Долговато и не впечатляет.
Ищем пути решения проблемы, находим на php.net, другой вариант фунции сравнения, который, как там написанно, должен работать быстрее:
|
Итого: 23.11 сек. Хреновая оптимизация…
Ладно, хорошо, со временем выполнения мы определились. Давайте попробуем определится с «расширяемостью кода». Допустим нам поставили задачу отсортировать сначала по ключу year а затем по ключу author. Для этого нам приходится переписывать всю «дополнительную функцию», в итоге получаем что то похожее на это:
|
Громоздко. Сложно изменять. Вообщем отстой, на мой взгляд.
Итак, подведем итоги. Минусы:
- Долго выполняется
- Сложно расширять
- Под каждую сортировку нужна своя, новая функция
Плюсы:
- Единственный очевидный вариант (?)
Пробуем костыли
Попробуем написать свою функцию для сортировки массивов с блекджеком и шлюхами. Напомню, наша задача сортировать многомерный массив по ключу:
|
Засекаем. Получаем: 7.90 сек. Ну уже не плохо впринципе.
Да вот только заставить этот костыль сортировать по двум ключам уже не получится, к сожалению. Подведем итоги. Минусы:
- Невозможно расширять
- Сортировка только по одному ключу
Плюсы
- Приемлимая скорость выполнения
- Одна функция для разных видов сортировки
Функция array_multisort
Оказывается разработчики PHP уже давным давно все придумали до нас. Оказывается есть функция array_multisort. Как работает эта функция:
array_multisort( array &$arr [, array &$arr [, array &$arr... ]] )
Грубо говоря каждый массив будет отсортирован в соответствии с предыдущим массивом. Вообщем пример:
|
Выведет:array(4) {
А это как раз то что нам надо! Возвращаемся к тестам на скорость:
[0]=> string(3) "bar"
[1]=> string(3) "foobar"
[2]=> string(3) "foo"
}
|
Засекаем. Получаем: 3.87 сек. Это рекорд!
Ну то что это самый быстрый вариант мы определили. Это хорошо. А как насчет расширяемости? Как к примеру заставить сортировать массив по двум ключам? Оказывается с этой функцией очень просто! Достаточно добавить еще один «определяющий массив», вот так:
|
На выходе получим вот такой массив:
|
Как видите функция справилась со своей задачей. Наш массив отсортирован сначала по year, затем по author. А с помощью различных флагов типа SORT_DESC, SORT_ASC и тд можно добится любой сортировки (про них подробнее смотрите в мане), так что это на мой взгляд самый лучший вариант для использования в своих скриптах.
Минусы
- ??
Плюсы
- Лучшая скорость
- Расширяемость
- Функциональность
Заключение
Вообщем используйте array_multisort для сортировки многомерных массивов. И будет вам счастье.
Источник: http://intsystem.org