- Сортировка массивов
- Сортировка массива по ключу
- Результат:
- Сортировка массива по значению
- Результат:
- Результат:
- Естественная сортировка
- Результат:
- Результат:
- Сортировка многомерных массивов
- Результат:
- Сортировка многомерного массива по значению одного ключа
- Результат:
- Перемешать массив
- Результат:
- Сортировка массивов в php: ksort, asort и прочие sort’ы
- Допустим у нас есть массив
- Сортировка массива по ключу
- Сортировка массива по значению
- Свои способы сортировки
- Сортировка многомерных массивов
- Создадим функцию, которая нам поможет в сортировке массивов
- Пример работы этой функции array_orderby() :
- Если вам нужно что-то совсем уж специфическое при сортировки многомерных массивов
- Массивы на «стероидах»
Сортировка массивов
В продолжении темы работы с массивами поговорим о типичной задаче – их сортировке. Для ее выполнения в PHP существует множество функций, их подробное описание можно посмотреть на php.net, рассмотрим некоторые примеры.
Сортировка массива по ключу
ksort() и krsort() – сортирует массив по ключу.
$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: ksort($array); print_r($array); // По убыванию: krsort($array); print_r($array);
Результат:
Array ( [1] => апельсин [3] => яблоко [5] => виноград ) Array ( [5] => виноград [3] => яблоко [1] => апельсин )
Сортировка массива по значению
Функции sort() и rsort() сортирует массив по значению, при этом не сохраняя ключи.
$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: sort($array); print_r($array); // По убыванию: rsort($array); print_r($array);
Результат:
Array ( [0] => апельсин [1] => виноград [2] => яблоко ) Array ( [0] => яблоко [1] => виноград [2] => апельсин )
Чтобы сохранить ключи применяется функции asort() и arsort() .
$array = array( 3 => 'яблоко', 1 => 'апельсин', 5 => 'виноград' ); // По возрастанию: asort($array); print_r($array); // По убыванию: arsort($array); print_r($array);
Результат:
Array ( [1] => апельсин [5] => виноград [3] => яблоко ) Array ( [3] => яблоко [5] => виноград [1] => апельсин )
Естественная сортировка
Выше приведенные функции по умолчанию используют алгоритм Quicksort (быстрая сортировка). Чтобы изменить алгоритм нужно вторым аргументом указать флаг:
SORT_REGULAR | Обычное сравнение элементов (без изменения типов) |
SORT_NUMERIC | Числовое сравнение элементов |
SORT_STRING | Строковое сравнение элементов |
SORT_LOCALE_STRING | Сравнивает элементы как строки с учетом текущей локали. |
SORT_NATURAL | Также как natsort() |
SORT_FLAG_CASE | Может быть объединен с SORT_STRING или SORT_NATURAL для сортировки строк без учета регистра. |
Привычную для человека сортировку делают функции natsort() , natcasesort() или флаг SORT_NATURAL .
natcasesort() сортирует массив без учета регистра символов.
Разницу можно увидеть в примере:
$array = array(-1, 0, 10, 'текст', 'a', 'b'); // Quicksort: sort($array); print_r($array); // Natural order: natsort($array); print_r($array);
Результат:
Array ( [0] => -1 [1] => a [2] => b [3] => 0 [4] => текст [5] => 10 ) Array ( [0] => -1 [1] => 0 [2] => 10 [4] => a [5] => b [3] => текст )
У natsort() нет возможности изменить направление сортировки, поэтому можно применить функцию array_reverse() .
natsort($array); $array = array_reverse($array); print_r($array);
Результат:
Array ( [0] => текст [1] => b [2] => a [3] => 10 [4] => 0 [5] => -1 )
Сортировка многомерных массивов
array_multisort() сортирует многомерные массивы по значению, также может отсортировать сразу несколько массивов.
$array = array( array(20, 222, 2, 22), array(10, 111, 1, 11), ); array_multisort($array); print_r($array);
Результат:
Array ( [0] => Array( [0] => 10 [1] => 111 [2] => 1 [3] => 11 ) [1] => Array( [0] => 20 [1] => 222 [2] => 2 [3] => 22 ) )
Чтобы изменить направление сортировки вторым аргументом функции указывается SORT_ASC или SORT_DESC .
array_multisort($array, SORT_DESC); print_r($array);
Сортировка многомерного массива по значению одного ключа
Есть несколько вариантов, первый – uasort() , сортирует массив, используя пользовательскую функцию для сравнения элементов и сохранением ключей.
В примере сортировка идет по ключу « count ».
$array = array( array( 'sku' => '645908-463', 'count' => '1' ), array( 'sku' => '64590644', 'count' => '20' ), array( 'sku' => '7543', 'count' => '2' ) ); // По возрастанию: function cmp_function($a, $b) < return ($a['count'] >$b['count']); > uasort($array, 'cmp_function'); print_r($array); // По убыванию: function cmp_function_desc($a, $b) < return ($a['count'] < $b['count']); >uasort($array, 'cmp_function_desc'); print_r($array);
Результат:
Array ( [0] => Array( [sku] => 645908-463 [count] => 1 ) [2] => Array( [sku] => 7543 [count] => 2 ) [1] => Array( [sku] => 64590644 [count] => 20 ) ) Array ( [1] => Array( [sku] => 64590644 [count] => 20 ) [2] => Array( [sku] => 7543 [count] => 2 ) [0] => Array( [sku] => 645908-463 [count] => 1 ) )
Второй вариант на основе функции array_multisort() :
function array_multisort_value() < $args = func_get_args(); $data = array_shift($args); foreach ($args as $n =>$field) < if (is_string($field)) < $tmp = array(); foreach ($data as $key =>$row) < $tmp[$key] = $row[$field]; >$args[$n] = $tmp; > > $args[] = &$data; call_user_func_array('array_multisort', $args); return array_pop($args); > $array = array( array( 'sku' => '645908-463', 'count' => '1' ), array( 'sku' => '64590644', 'count' => '20' ), array( 'sku' => '7543', 'count' => '2' ) ); $array = array_multisort_value($array, 'count', SORT_DESC); print_r($array);
Перемешать массив
Функция shuffle() перемешивает массив в случайном порядке, не сохроняя ключи.
$array = array( 1 => 'яблоко', 2 => 'апельсин', 3 => 'виноград' ); shuffle($array); print_r($array); shuffle($array); print_r($array);
Результат:
Array ( [0] => виноград [1] => яблоко [2] => апельсин ) Array ( [0] => виноград [1] => апельсин [2] => яблоко )
Сортировка массивов в php: ksort, asort и прочие sort’ы
Более подробную информацию и примеры вы всегда можете найти в документации по функциям сортировки.
Допустим у нас есть массив
$arr = [ 2 => 'Виноград', 1 => 'Арбуз', 3 => 'Банан', ];
Он неправильно отсортирован, как видите ключи (1,2,3) и значения (виноград, арбуз, банан) идут не по порядку. Давайте это исправим:
Сортировка массива по ключу
ksort($arr); // По возрастанию krsort($arr); // По убыванию
Сортировка массива по значению
sort($arr);// По возрастанию asort($arr);// По возрастанию, сохраняет ключи rsort($arr); // По убыванию arsort($arr); // По убыванию, сохраняет ключи array_reverse($arr); // От конца к началу array_reverse($arr, true); // От конца к началу, сохраняет ключи shuffle($arr); // Перемешать массив в случайном порядке
Свои способы сортировки
Если предложенные способы сортировки вам не подходят, то можно создать свой способ сортировки ключей и значений массивов. Для этого есть 3 функции uasort, uksort и usort. С их помощью мы можем задать свою callback функцию, которая будет сравнивать элементы между собой и определять какой из них «больше» и какой «меньше».
- uasort — Сортирует массив, используя пользовательскую функцию для сравнения элементов с сохранением ключей
- uksort — Сортирует массив по ключам, используя пользовательскую функцию для сравнения ключей
- usort — Сортирует массив по значениям используя пользовательскую функцию для сравнения элементов
Принцип работы следующий, мы создаем callback функцию сравнения по какому-то необычному признаку. Она должна сравнивать элементы и возвращать одно из трех значений: -1, 0 или 1
Давайте рассмотрим как они работают напримере функции uasort, которая сравнивает значения с сохранением ключей.
// Наша функция сравнения $callbackCmpFunction = function cmp($a, $b) < if ($a == $b) < // если 2 значения массива равны return 0; // вернем 0 >return ($a
- -1 — возвращается, когда элемент, который слева больше правого
- 0 — когда элементы равны
- 1 — когда правый больше левого
Применить нашу новую функцию можно так:
// Сортируемый массив $array = array('a' => 4, 'b' => 8, 'c' => -1, 'd' => -9, 'e' => 2, 'f' => 5, 'g' => 3, 'h' => -4); print_r($array); // Сортируем и выводим получившийся массив uasort($array, $callbackCmpFunction); // вторым параметром указываем нашу callback функцию print_r($array);
Сохранение ключей означает, что каждый ключ как бы привязан к своему значению.
Функции без сохранения ключей sort и rsort, сбрасывают ключи и они начинают идти по порядку (0, 1, 2, . )
Иногда бывает полезно одно, иногда — другое. В зависимости от задачи.
Если сортировка не дает ожидаемый результат, то изучите флаги сортировки. По умолчанию используется обычный тип сортировки SORT_REGULAR
- SORT_REGULAR — обычное сравнение элементов; подробности описаны в разделе операторы сравнения
- SORT_NUMERIC — числовое сравнение элементов
- SORT_STRING — строковое сравнение элементов
- SORT_LOCALE_STRING — сравнение элементов как строки на основе текущего языкового стандарта. Используется языковой стандарт, который можно изменить с помощью setlocale()
- SORT_NATURAL — сравнение элементов как строки, используя «естественный порядок», например natsort()
- SORT_FLAG_CASE — можно объединять (побитовое ИЛИ) с SORT_STRING или SORT_NATURAL для сортировки строк без учёта регистра. Пример: sort($arr, SORT_NATURAL | SORT_FLAG_CASE)
Флаг сортировки передается в функцию сортировки, например так:
Сортировка многомерных массивов
Создадим функцию, которая нам поможет в сортировке массивов
// создадим функцию которая нам поможет в сортировке массивов function array_orderby() < $args = func_get_args(); $data = array_shift($args); foreach ($args as $n =>$field) < if (is_string($field)) < $tmp = array(); foreach ($data as $key =>$row) $tmp[$key] = $row[$field]; $args[$n] = $tmp; > > $args[] = &$data; call_user_func_array('array_multisort', $args); return array_pop($args); >
Пример работы этой функции array_orderby() :
$data = [ ['volume' => 67, 'edition' => 2], ['volume' => 86, 'edition' => 1], ['volume' => 85, 'edition' => 6], ['volume' => 98, 'edition' => 2], ['volume' => 86, 'edition' => 6], ['volume' => 67, 'edition' => 7], ]; // Сортируем массив $data сначала по volume, затем по edition $sorted = array_orderby($data, 'volume', SORT_DESC, 'edition', SORT_ASC); // SORT_ASC - по возрастанию // SORT_DESC - по убыванию print_r($sorted); // выводим результат
Если вам нужно что-то совсем уж специфическое при сортировки многомерных массивов
Можете создать и другие callback функции сортировки самостоятельно.
$data = [ ['volume' => 67, 'edition' => 2], ['volume' => 86, 'edition' => 1], ['volume' => 85, 'edition' => 6], ['volume' => 98, 'edition' => 2], ['volume' => 86, 'edition' => 6], ['volume' => 67, 'edition' => 7], ]; // Создадим 2 функции function cmp_function($a, $b) < // volume по возрастанию return ($a['volume'] >$b['volume']); > function cmp_function_desc($a, $b) < // volume по убыванию return ($a['volume'] < $b['volume']); >uasort($array, 'cmp_function'); // сортируем по возрастанию, по полю count uasort($array, 'cmp_function_desc'); // сортируем по убыванию, по полю count
Массивы на «стероидах»
Часто работаете с массивами? Тогда вам понравится это расширение для работы с коллекциями.
Рассмотрим несколько примеров.
$collection = collect([5, 3, 1, 2, 4]); $sorted = $collection->sort(); $sorted->values()->all(); // [1, 2, 3, 4, 5]
Сортировка по одной «колонке» ассоциативного массива:
$collection = collect([ ['name' => 'Desk', 'price' => 200], ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ]); $sorted = $collection->sortBy('price'); $sorted->values()->all(); /* [ ['name' => 'Chair', 'price' => 100], ['name' => 'Bookcase', 'price' => 150], ['name' => 'Desk', 'price' => 200], ] */
Сортировка по нескольким аттрибутам одновременно:
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32], ]); $sorted = $collection->sortBy([ ['name', 'asc'], ['age', 'desc'], ]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ] */
Вы также можете использовать свои функции сортировки при работе с коллекциями:
$collection = collect([ ['name' => 'Taylor Otwell', 'age' => 34], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Abigail Otwell', 'age' => 32], ]); $sorted = $collection->sortBy([ fn ($a, $b) => $a['name'] $b['name'], fn ($a, $b) => $b['age'] $a['age'], ]); $sorted->values()->all(); /* [ ['name' => 'Abigail Otwell', 'age' => 32], ['name' => 'Abigail Otwell', 'age' => 30], ['name' => 'Taylor Otwell', 'age' => 36], ['name' => 'Taylor Otwell', 'age' => 34], ] */
Коллекции позволяют работать с массивами как в Laravel и функции этого замечательного инструмента далеко не ограничиваются сортировкой.
Изучите документацию и вы влюбитесь в коллекции.
Если у вас есть вопросы или вы нашли ошибку — пишите в комментариях.