Этот вопрос предназначен в качестве справочного материала для вопросов о сортировке массивов в PHP. Легко представить, что ваш конкретный случай уникален и заслуживает нового вопроса, но большинство из них на самом деле являются незначительными вариациями одного из решений на этой странице.
Если ваш вопрос закрыт как дубликат этого вопроса, пожалуйста, попросите, чтобы ваш вопрос был открыт повторно, только если вы можете объяснить, почему он заметно отличается от всего нижеприведенного.
Как отсортировать массив в PHP?
Как отсортировать сложный массив в PHP?
Как отсортировать массив объектов в PHP?
Для практического ответа с использованием существующих функций PHP см. 1., для академического подробного ответа об алгоритмах сортировки (которые реализуют функции PHP и которые вам могут понадобиться в действительно очень сложных случаях), см. 2.
Ответы:
Основные одномерные массивы
Применимые функции сортировки:
sort
rsort
asort
arsort
natsort
natcasesort
ksort
krsort
Разница между ними заключается лишь в том, сохраняются ли ассоциации ключ-значение (
a
«функции»), сортируется ли он по возрастанию или наоборот («r
»), сортирует ли он значения или ключи («k
») и как он сравнивает значения ("nat
" против нормального). Смотрите http://php.net/manual/en/array.sorting.php для обзора и ссылки на дополнительную информацию.Многомерные массивы, в том числе массивы объектов
Если вы хотите сортировать
$array
по ключу 'foo' каждой записи, вам нужна специальная функция сравнения . Вышеуказанныеsort
и связанные функции работают с простыми значениями, которые они умеют сравнивать и сортировать. PHP не просто «знает», что делать со сложным значением, вродеarray('foo' => 'bar', 'baz' => 42)
; так что вы должны сказать это.Для этого вам нужно создать функцию сравнения . Эта функция принимает два элемента и должна возвращать,
0
если эти элементы считаются равными, значение ниже, чем,0
если первое значение ниже, и значение выше, чем,0
если первое значение выше. Вот и все, что нужно:Часто вы хотите использовать анонимную функцию в качестве обратного вызова. Если вы хотите использовать метод или статический метод, посмотрите другие способы указания обратного вызова в PHP .
Затем вы используете одну из этих функций:
usort
uasort
uksort
Опять же, они отличаются только тем, сохраняют ли они ассоциации ключ-значение и сортируют по значениям или ключам. Прочитайте их документацию для деталей.
Пример использования:
usort
возьмет два элемента из массива и вызоветcmp
с ними вашу функцию. Такcmp()
будет называться$a
какarray('foo' => 'bar', 'baz' => 42)
и$b
как другоеarray('foo' => ..., 'baz' => ...)
. Затем функция возвращает то,usort
какое из значений было больше или были ли они равны.usort
повторяет этот процесс, передавая разные значения для$a
и$b
до сортировки массива.cmp
Функция будет вызываться много раз, по крайней мере , столько раз , сколько есть значения в$array
, с различными комбинациями значений$a
и$b
каждый раз.Чтобы привыкнуть к этой идее, попробуйте это:
Все, что вы сделали, это определили собственный способ сравнения двух элементов, это все, что вам нужно. Это работает со всеми видами ценностей.
Кстати, это работает для любого значения, значения не должны быть сложными массивами. Если у вас есть пользовательское сравнение, которое вы хотите сделать, вы можете сделать это и на простом массиве чисел.
sort
сортирует по ссылке и не возвращает ничего полезного!Обратите внимание, что массив сортируется на месте , вам не нужно присваивать возвращаемое значение чему-либо.
$array = sort($array)
заменит массив наtrue
, а не на отсортированный массив. Простоsort($array);
работает.Пользовательские числовые сравнения
Если вы хотите отсортировать по
baz
числовому ключу, все, что вам нужно сделать, это:Благодаря PoWEr oF MATH это возвращает значение <0, 0 или> 0 в зависимости от того
$a
, меньше, равно или больше, чем$b
.Обратите внимание, что это не будет хорошо работать для
float
значений, так как они будут уменьшены доint
и потеряют точность. Используйте явное-1
,0
и1
возвращать значения вместо этого.Объекты
Если у вас есть массив объектов, он работает так же:
функции
Внутри функции сравнения вы можете делать все, что вам нужно, в том числе вызывать функции:
Струны
Ярлык для первой версии сравнения строк:
strcmp
делает именно то , что ожидаетсяcmp
здесь, он возвращается-1
,0
или1
.Оператор космического корабля
В PHP 7 появился оператор космического корабля , который объединяет и упрощает равные / меньшие / большие, чем сравнения по типам:
Сортировка по нескольким полям
Если вы хотите отсортировать в первую очередь по
foo
, но еслиfoo
равно для двух элементов, сортируйте поbaz
:Для тех, кто знаком, это эквивалентно запросу SQL с
ORDER BY foo, baz
.Также посмотрите эту очень аккуратную сокращенную версию и как динамически создать такую функцию сравнения для произвольного числа ключей .
Сортировка в ручную, статический порядок
Если вы хотите отсортировать элементы в «ручной порядок», например, «foo», «bar», «baz» :
Для всего вышеперечисленного, если вы используете PHP 5.3 или выше (и вам действительно следует), используйте анонимные функции для более короткого кода и во избежание появления другой глобальной функции:
Вот как может быть проста сортировка сложного многомерного массива. Опять же, просто подумайте с точки зрения обучения PHP, как определить, какой из двух элементов «больше» ; позвольте PHP сделать фактическую сортировку.
Также для всего вышеперечисленного, чтобы переключаться между восходящим и нисходящим порядком, просто поменяйте местами аргументы
$a
и$b
. Например:Сортировка одного массива на основе другого
И еще есть особенность
array_multisort
, которая позволяет сортировать один массив на основе другого:Ожидаемый результат здесь будет:
Используйте,
array_multisort
чтобы попасть туда:Начиная с PHP 5.5.0, вы можете использовать,
array_column
чтобы извлечь столбец из многомерного массива и отсортировать массив по этому столбцу:Начиная с PHP 7.0.0 вы также можете извлекать свойства из массива объектов.
источник
array_flip()
более быстрый поиск позиции, например,$order[$a['foo']]
вместоarray_search($a['foo'], $order)
.Ну, большинство базовых методов уже охвачены deceze, я бы попробовал взглянуть на другие типы сортировки.
Сортировка с SPL
SplHeap
Вывод
SplMaxHeap
Класс SplMaxHeap обеспечивает основные функциональные возможности кучи, сохраняя максимум на вершине.
SplMinHeap
Другие типы сортировки
Пузырьковая сортировка
Из статьи Википедии о Bubble Sort:
Сортировка выбора
Из статьи Википедии о сортировке выбора:
Вид вставки
Из статьи Википедии о сортировке вставок:
ShellSort
Из статьи в Википедии о Shellsort:
Расческа
Из статьи в Википедии о сортировке Расчески:
Сортировка слиянием
Из статьи в Википедии о сортировке слиянием:
Quicksort
Из статьи в Википедии о быстрой сортировке:
Перестановка сортировки
Из статьи Википедии о перестановочной сортировке:
Radix sort
Из статьи в Википедии о сортировке Radix:
источник
O(n^2)
сравнение, если мы будем использовать только первый элемент в качестве сводного)Стабильный сорт
Допустим, у вас есть такой массив:
А теперь вы хотите отсортировать только по первой букве:
Результат таков:
Сорт не был стабильным!
Зоркий наблюдатель, возможно, заметил, что алгоритм сортировки массива (QuickSort) не дал стабильного результата и что первоначальный порядок между словами одной и той же первой буквы не сохранился. Этот случай тривиален, и мы должны были сравнить всю строку, но давайте предположим, что ваш вариант использования более сложный, например, два последовательных сортировки в разных полях, которые не должны отменять работу друг друга.
Преобразование Шварца
Преобразование Шварца , также называемое идиомой decorate-sort-undecorate, обеспечивает устойчивую сортировку с помощью изначально нестабильного алгоритма сортировки.
Сначала вы декорируете каждый элемент массива другим массивом, содержащим первичный ключ (значение) и вторичный ключ (его индекс или позицию):
Это преобразует массив в это:
Теперь настроим шаг сравнения; мы снова сравниваем первую букву, но если они совпадают, вторичный ключ используется для сохранения исходного порядка:
После этого мы декорируем:
Конечный результат:
Как насчет повторного использования?
Вы должны были переписать свою функцию сравнения для работы с преобразованными элементами массива; Вы можете не захотеть редактировать свои тонкие функции сравнения, поэтому вот обертка для функции сравнения:
Давайте напишем шаг сортировки, используя эту функцию:
Вуаля! Ваш первоначальный код сравнения вернулся.
источник
Начиная с PHP 5.3 с замыканиями, также можно использовать замыкание для определения порядка вашего рода.
Например, предположим, что $ array является массивом объектов, которые содержат свойство month.
источник
LINQ
В .NET LINQ часто используется для сортировки, что обеспечивает гораздо более приятный синтаксис по сравнению с функциями сравнения, особенно когда объекты должны быть отсортированы по нескольким полям. Существует несколько портов LINQ to PHP, включая библиотеку YaLinqo *. С его помощью массивы можно сортировать одной строкой без написания сложных функций сравнения.
Сравнения могут быть дополнительно настроены путем передачи обратного вызова в качестве второго аргумента, например:
Здесь
'$v->count'
сокращение дляfunction ($v) { return $v->count; }
(может использоваться любой). Эти цепочки методов возвращают итераторы, итераторы можно преобразовать в массивы, добавив->toArray()
в конце при необходимости.Внутренне,
orderBy
и связанные с ними методы вызывают соответствующие функции сортировки массива (uasort
,krsort
,multisort
, иusort
т.д.).LINQ содержит гораздо больше методов, основанных на SQL: фильтрация, группирование, объединение, агрегирование и т. Д. Он лучше всего подходит для случаев, когда необходимо выполнять сложные преобразования массивов и объектов без использования баз данных.
* разработанный мной, см. readme для более подробной информации и сравнения с другими портами LINQ
источник
Многомерная сортировка по значению ключа
Естественная сортировка многомерного массива по значению ключа, а также сохранение исходного порядка (не перемешивайте основные ключи):
Прецедент:
источник
Сортировать массивы с помощью отсортированной функции из Nspl очень удобно :
Базовая сортировка
Сортировка по результату функции
Сортировка многомерного массива
Сортировка массива объектов
Сортировка с функцией сравнения
Вы можете увидеть все эти примеры здесь .
источник
Если вы хотите заказать по значению ключа, то вы можете сделать это одной строкой, элегантно и понятно. Это будет порядок по возрастанию цены. Использует array_multisort и array_column.
производить
источник
Эта страница очень полная, но я хочу добавить немного больше об удивительной полезности оператора космического корабля (трехстороннего оператора сравнения) - прекрасного потомка PHP7 +.
Использование оператора космического корабля для реализации нескольких условий сортировки
Это делает большие успехи в уменьшении раздувания кода и улучшении читаемости.
При написании пользовательской функции сортировки (
usort()
/uasort()
/uksort()
) для обработки нескольких условий вам нужно только написать сбалансированные массивы по обе стороны от оператора и вернуть результат. Нет больше вложенных блоков условий или множественных возвратов.Элементы с обеих сторон оператора будут перемещаться слева направо, по одному, и возвращать оценку, как только встретится несвязывание или когда все элементы будут сопоставлены.
Пример данных для моих демонстраций:
Демонстрации (чтобы избежать раздувания страницы Stackoverflow, см. Демонстрационную ссылку для выходов):
Логика сортировки:
плавать ASC
Логика сортировки:
логический ASC
Логика сортировки:
natString ASC
Этот синтаксис позволяет элегантно сортировать значения, функциональные результаты, данные с глубоким вложением и направление сортировки. Это определенно стоит добавить в ваш php toolbelt ... для случаев, когда вы обрабатываете данные не из базы данных - потому что, конечно, SQL был бы гораздо более разумным методом.
На ваше усмотрение, начиная с PHP7.4, вы можете использовать синтаксис стрелок с этими анонимными функциями. Тот же скрипт с синтаксисом стрелок .
источник
Если кто-то хочет более простое решение для манипулирования массивами, просто используйте пакет Laravel Collection, в котором реализована функция sortBy, которая позволяет просто сортировать по ключам.
то есть, чтобы отсортировать сначала по a, затем b, затем c, правильное предложение будет
https://packagist.org/packages/tightenco/collect
источник
Существует несколько способов сортировки массива. Я упомяну некоторые методы для выполнения этой задачи. Из всех я приведу целочисленный массив, который называется «$ numbers».
Это нормальный способ создания массива. Предположим, что я хочу отсортировать этот массив в порядке возрастания. Для этого можно использовать метод sort ().
Теперь рассмотрим вывод этого,
Вы можете видеть, что напечатанный массив чисел отсортирован. Если вы хотите, чтобы этот числовой массив сортировался в порядке убывания, для этой задачи можно использовать метод rsort ().
рассмотрим вывод ..
Теперь массив отсортирован в порядке убывания. Хорошо, давайте рассмотрим ассоциативный массив. Я дам ассоциативный массив (ассоциативный массив означает, что массив, каждый индекс которого имеет уникальное значение ключа).
Итак, теперь я хочу отсортировать этот массив в порядке возрастания в соответствии с их значением. Для этого можно использовать метод 'asort ()'.
При сортировке в порядке убывания по их значению можно использовать метод «arsort ()». Предположим, что вы хотите отсортировать этот массив по значению ключа. В этом случае можно использовать метод ksort ().
Теперь рассмотрим вывод.
Теперь массив сортируется по значению ключа. Если вы хотите отсортировать массив в порядке убывания по значению ключа, можно использовать метод krsort ().
Теперь ассоциативный массив отсортирован в порядке убывания по значению ключа. Посмотрите на вывод.
Вот некоторые методы для сортировки массива в порядке возрастания или убывания в php. Я надеюсь, что вы могли бы получить представление. Спасибо!
источник
Самое простое - использовать функцию usort для сортировки массива без зацикливания: ниже приведен пример:
Это будет сортировать в порядке убывания:
Это будет сортировать в порядке возрастания:
источник