Программы. Игры. Браузеры. Windows. Архиваторы
  • Главная
  • Программы для ПК
  • Php сортировка двумерного массива по нужному полю. Как сортировать многомерный массив в PHP. Функции сортировки массива php

Php сортировка двумерного массива по нужному полю. Как сортировать многомерный массив в PHP. Функции сортировки массива php

3.5K

Благодаря своей мощности и гибкости в работе массивы стали непременным атрибутом PHP . Причем, в ряде сложных ситуаций можно задействовать и двумерные массивы PHP . Данная статья посвящена сортировке многомерных массивов в PHP .

Составляющие :

  • Многомерный массив;
  • Встроенные функции PHP usort () , uasort () или uksort () ;
  • Встроенные функции PHP strcasecmp() или strcmp() .

Реализация :
Допустим что, у нас есть массив:

$students = array (1 => array ("name" => "Jack", "grade" => 98.5), 2 => array ("name" => "Bill", "grade" => 90.1), 3 => array ("name" => "Chloe", "grade" => 94.0), 4 => array ("name" => "Taylor", "grade" => 95.1), 5 => array ("name" => "Larry", "grade" => 94.6));

Здесь можно осуществить сортировку двумерного массива PHP по параметру grade (оценка ) (числовая сортировка ) или name (имя ) (сортировка в алфавитном порядке ).

Внешний массив $students состоит из пяти элементов, каждый из которых также представлен в виде отдельного массива. Внутренний массив использует ID студента в качестве ключа и хранит два значения: имя студента и его оценку.

Для сортировки многомерного массива мы задаем собственную функцию. Говорим PHP , что именно ее нужно использовать для вызова встроенных функций usort () , uasort () или uksort () .

Определяемая функция должна принимать два параметра и возвращать значение, указывающее, какой именно параметр идет первым по списку. Отрицательное или false значение говорит о том, что первый параметр указывается до второго. Положительное или true — что вначале идет второй параметр. Нулевое значение (0 ) указывает, что оба параметра равнозначны.

A – Сортировка по оценке (параметр grade) (числовая сортировка)

Определим функцию для сортировки массива по оценке (параметр grade ):

// Функция сортировки по оценке: сортировка по УБЫВАНИЮ. function grade_sort($x, $y) { if ($x[" оценка "] < $y[" оценка "]) { return true; } else if ($x["оценка"] > $y["оценка"]) { return false; } else { return 0; } }

Затем возьмем пользовательскую функцию и осуществим перебор двумерного массива PHP по первому ключу. Выглядит это примерно так:

// $students – наш многомерный массив, а grade_sort – созданная функция usort ($students, " grade_sort ");

Пример :

// Вызвать на печать массив в виде (начальный массив): echo "

Массив в виде

" . print_r($students, 1) . "
"; // Сортировать по оценке (grade): uasort($students, "grade_sort"); echo "

Массив отсортирован по оценке

" . print_r($students, 1) . "
";

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

function grade_sort($x, $y) { static $count = 1; echo “

Iteration $count: {$x[‘оценка’]} vs. {$y[‘оценка’]}

n”; $count++; if ($x[‘ оценка ‘] < $y[‘ оценка ‘]) { return true; } else if ($x[‘ключ1′] > $y[‘ключ1′]) { return false; } else { return 0; } }

Выводя на экран значения $x[‘оценка’] и $y [‘оценка’] , можно увидеть, как вызывается функция сортировки, определенная пользователем.

Можно сократить функцию grade_sort следующим образом:

// Функция числовой сортировки по оценке: сортировка по УБЫВАНИЮ function grade_sort($x, $y) { return ($x["grade"] < $y["grade"]); }

Результаты сортировки двумерного массива PHP по оценке отображены на картинке ниже:


Примечание : Функция usort () сортирует по значениям, но не сохраняет ключи (для внешнего массива ). Если ключи нужны, то лучше использовать функцию uasort () .

B – Сортировка по имени (в алфавитном порядке)

Чтобы отсортировать массив $students по первому ключу, необходимо сравнить две строки. Поэтому в примере с сортировкой в алфавитном порядке воспользуемся функция strcasecmp() (не чувствительна к регистру ) и strcmp() (чувствительна к регистру ). Получившийся двумерный массив PHP будет иметь следующий вид.

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

И одна из них, с которой лично мне приходится достаточно часто встречаться на работе, – это сортировка массива php .

Такие частые встречи были обусловлены тем, что, как показывает практика, люди любят время от времени, для разнообразия, менять последовательность вывода объектов на своём сайте – будь то товары в Интернет-магазине, сообщения пользователей на форуме или блоки информации на сайтах-визитках.

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

Немного теории о массивах php

PHP – это серверный язык программирования. Серверный, потому что скрипты, которые запускаются пользователями через веб-интерфейс (Интернет-браузер), хранятся и выполняются на сервере.

PHP-скрипты скрыты от взора обычного пользователя. В окне ваших браузеров вы видите только результаты их выполнения.

Массив в программировании – это совокупность каких-то данных. Состоят они из элементов массива, которые представляют собой пары [индекс] => [значение].

Массивы бывают статические, динамические, гетерогенные и т.д. (целая наука) 🙂 Нам же для работы с ними вполне хватит классификации на одномерные и многомерные.

Для того, чтобы вы поняли разницу между ними, достаточно привести описание их структуры.

Одномерый массив php:

Array ( => 1 => 2 => 3)

Многомерный массив php:

Array ( => Array ( => 1) => Array ( => 2) => Array ( => 3))

Заметили? Если нет – обратите внимание на элементы многомерного массива php. Они сами являются массивами. Т.е. многомерный массив – это совокупность массивов. Уровень их вложенности может быть сколько угодно большим.

Теперь, думаю, точно понятно 🙂

Также ещё хотелось бы отдельно выделить понятие ассоциативного массива php. В реальной жизни они не так распространены, как обычные, но всё же имеют место быть.

Вкратце, это такие массивы, у которых ключ и значение элемента массива неразрывно связаны и между ними прослеживается некая логическая связь, которую ни в коем случае нельзя разрывать.

Примером ассоциативного массива может служить следующая конструкция:

Array ( => 12 [фио] => Иванов Иван Иванович [средний_балл] => 3)

Как видите, здесь значения ключей и значений элементов массива тесно связаны и ни в коем случае нельзя разрывать эту связь. Благодаря этому ассоциативные массивы очень часто называют «словарями» или «справочниками».

Поэтому данную особенность нужно обязательно учитывать при сортировке массива php, т.к. для таких структур подойдут не все методы.

В самом php массивы создаются двумя способами:

  1. $books = array(‘Азбука’, ‘Букварь’, ‘Словарь); или $books = array(‘azb’ => ‘Азбука’, ‘buk’ => ‘Букварь’, ‘slov’ => ‘Словарь’); Второй вариант используется, когда элементу нужно явно указать ключевое поле (актуально для ассоциативных массивов). Если его не указать, по умолчанию ключи элементов массива будут числами. Начиная с 0 (нуля).
  2. $books = ‘Азбука’; $books = ‘Букварь’; $books = ‘Букварь’;

В обоих случаях $books будет являться массивом. Так что, если вы встретите в коде своего сайта такие конструкции, это уже не будет для вас чем-то непонятным 🙂

Если вы хотите узнать о массивах php более подробно, то рекомендую вашему вниманию следующее видео:

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

Echo "

"; print_r(переменная_массива); die();
 

Если распечатываемая вами переменная будет являться массивом, то текст будет начинаться со следующей строки:

Array (…

И ещё несколько слов о теме нашей статьи – сортировке массивов php .

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

Поэтому всё, что нам нужно сделать – это вызвать требуемую функцию после объявления массива, указав его в качестве параметра.

Переходим к обзору самих функций.

Функции сортировки массива php

Их полный перечень представлен в официальной документации языка php:

Для того, чтобы произвести сортировку массива php с помощью какой-то конкретной функции, нужно будет вызвать её после объявления массива и заполнения его значениями, указав ей в качестве параметров наш массив. Например:

$cars = array("Toyota", "Mazda", "Mitsubishi"); sort($cars);

Рассмотрим вкратце функционал каждой из них. Функции будут указаны в том формате, в котором их нужно будет вызывать в коде, т.е. «название(параметр1, параметр2, …);».

Не забудьте после вызова функции поставить «;», т.к. без неё на экране появится красивое сообщение об ошибке 🙂

В качестве наглядного примера возьмём простой одномерный массив, в котором будут неупорядочены как ключи, так и значения, чтобы результаты выполнения функций были более наглядны и понятны.

Array ( => 11 => 18 => 9)

Итак, как же можно произвести сортировку массива в нужном порядке на php?

Функции простой сортировка массива php по значению

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

Если после него у вас остались вопросы, то более подробную информацию по каждой функции вы можете найти ниже.

sort($array, $flag); — одна из самых простых и востребованных функций. Позволяет отсортировать массив по возрастанию на php с учетом значений элементов, т.е. они будут расположены от меньшего значения к большему. В качестве параметров принимает переменную массива и один из флагов сортировки, который позволяет изменить поведение сортировки.

Список флагов:

  • SORT_REGULAR – элементы сравниваются без изменения типов
  • SORT_NUMERIC – элементы сравниваются как числа
  • SORT_STRING – элементы сравниваются как строки
  • SORT_LOCALE_STRING – строковое сравнение, но с учетом текущей локали.
  • SORT_NATURAL – строковое сравнение элементов, учитывая их естественный порядок (как у natsort)
  • SORT_FLAG_CASE – сортировка элементов массива php без учёта регистра (можно объединять с SORT_STRING или SORT_NATURAL побитовым ИЛИ).

Но, в большинстве случаев, результат выполнения функции является корректным и без этих уточняющих флагов. По умолчанию (если ничего не указать) будет использоваться SORT_REGULAR.

Наш тестовый массив после вызова функции sort() будет выглядеть следующим образом:

Array ( => 9 => 11 => 18)

Как видите, после сортировки массива по значениям, значения их ключей также поменялись, т.к. sort работает без сохранения связи «ключ-значение», о чём говорится в официальной документации php.

В итоге, данный вариант подойдёт для подавляющего большинства случаев.

rsort($array, $flag); — функция, являющаяся антагонистом sort. Антагонистом, потому что она производит сортировку массива таким же образом, только не по возрастанию, а по убыванию, т.е. первыми будут идти элементы массива php с самыми большими значениями.

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

Array ( => 18 => 11 => 9)

asort($array, $flag); — функция php для сортировки массива по значению, механизм работы которой также очень похож на sort.

За тем лишь исключением, что она позволяет производить сортировку массива php по значению его элементов с сохранением связи «ключ — значение».

Таким образом, данная функция отлично подходит для сортировки ассоциативных массивов php , т.е. структур, где данная связь логична и важна.

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

Также можно передавать два параметра. Наш тестовый массив примет следующий вид:

Array ( => 9 => 11 => 18)

Как видите, отличие от sort только в сохранении ключей у значений, по которым происходит сортировка массива php. Это и называется сохранением связи «ключ-значение», которая невероятно важна при сортировке ассоциативных массивов php.

arsort($array, $flag); — еще одна функция php для сортировки массива по значению. Антагонист asort.

Работает по тому же принципу, что и упомянутая функция, только сортировка массива php в данном случае будет по убыванию. Также является отличным вариантом при сортировке ассоциативных массивов php.

После вызова данной функции наш пример будет выглядеть так:

Array ( => 18 => 11 => 9)

Функции продвинутой сортировки массива php по значению

Данный блок функций, в отличие от предыдущих, которые позволяли менять порядок по убыванию/возрастанию, позволит внести разнообразие и расположить элементы в различных последовательностях, отличных от «традиционных».

Эта особенность делает их пригодными для решения различных нестандартных задач, порой весьма интересных 🙂

natsort($array); — данная функция вносит разнообразие в семейку sort-подобных решений, т.к. механизм её работы в корне отличается от них. У natsort есть всего один-единственный входной параметр – это сортируемый массив, значения которого будут расположены в порядке, привычном для человека. Такой алгоритм носит название «natural ordering», что по-русски означает «естественный порядок». Для того, чтобы был понятен смысл данного утверждения, мы в качестве примера возьмём другой массив:

Array ( => ученик5 => ученик1 => ученик10)

Кроме того, функция natsort сохраняет связь «ключ-значение». Поэтому её работу мы будет сравнивать с asort, которая максимально похожа на неё. После вызова последней наш массив примет следующий вид:

Array ( => ученик1 => ученик10 => ученик5)

Если же вызвать natsort, то итоговый массив будет таким:

Array ( => ученик1 => ученик5 => ученик10)

Думаю, разница вам теперь видна и принцип работы natsort для вас будет понятен:-)

shuffle($array); — замечательная и очень полезная функция, с помощью которой можно перемешать массив php и разместить его элементы в случайном порядке.

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

При этом связь «ключ-значение» не сохраняется. То есть, массив, используемый нами в предыдущем примере, лично у меня принял вид:

Array ( => ученик10 => ученик5 => ученик1)

Причём, после каждого вызова функции порядок элементов будет различный.

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

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

Одним из таких задач является php по нужному полю.

Чтобы наглядно показать вам работу следующих функций, для примера возьмём следующий массив:

Array ( => Array ( => 32) => Array ( => 11) => Array ( => 27))

Как вы видите, он многомерный, т.к. его элементами являются массивы, структура которых идентична: они все имеют поле с ключом «id». И теперь наша задача – рассортировать эти элементы по возрастанию, т.е. чтобы в главном массиве элементы были расположены в соответствии со значением полей в подмассивах.

Нужно сказать, довольно распространённая задача. Решить её нам помогут следующие функции:

usort($array, ‘function’); — функция php сортировки многомерного массива по нужному полю.

Позволяет сделать сортировку элементов массива php без сохранения связи «ключ-значение» в соответствии с пользовательской функцией, имя которой передаётся в качестве второго параметра при вызове usort.

Сама функция описывается отдельно. Касательно нашего примера, для сортировки элементов многомерного массива php по полю [‘id’] в порядке возрастания пользовательская функция будет иметь следующий вид:

Function myCmp($a, $b) { if ($a["id"] == $b["id"]) return 0; return $a["id"] > $b["id"] ? 1: -1; }

Всё, что нам теперь нужно, чтобы запустить сортировку, это сделать вызов функции usort($array, ‘myCmp’); в необходимом месте кода. В качестве первого параметра указывает имя переменной массива.

В итоге мы получим следующее:

Array ( => Array ( => 11) => Array ( => 27) => Array ( => 32))

uasort($array, ‘function’); — ещё одна функция php сортировки многомерного массива по нужному полю.

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

Пользовательская функция для нашего примера будет та же самая. Результаты её выполнения будут выглядеть так:

Array ( => Array ( => 11) => Array ( => 27) => Array ( => 32))

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

Например, если у вас в массивах, которые являются элементами исходного, будет содержаться поле [‘name’] со строковым значением, то пользовательская функция для сортировки многомерного массива php по этому полю в порядке возрастания будет выглядеть так:

Function myCmp($a, $b) { if (strcasecmp($a["name"], $b["person"]["name"]) == 0) return 0; return strcasecmp($a["name"], $b["name"]) > 0 ? 1: -1; }

Сортировка массивов php с применением пользовательских функций — вариант не самый простой, но зато очень гибкий в настройке, и если овладеть им, то он станет вашим излюбленным решением.

array_multisort($array1, $array2, $flag); — напоследок я приберёг самую страшную и малопонятную функцию php для сортировки массива. В качестве входных параметров она принимает два массива и те же флаги сортировки, которые можно указывать у sort-подобных функций. Работает array_multisort следующим образом: первый параметр – сортируемый массив, в качестве второго массива указывается порядок сортировки первого, после чего второй массив сортируется по аналогии с первым. Вместо массива, отражающего порядок сортировки, можно использовать константы SORT_DESC для сортировки массива по убыванию и SORT_ASC по возрастанию. Ко всей этой путанице ещё можно добавлять флаги сортировки, которые могут идти после всех массивов.

$books = array(32, 11, 27); $sort_array = array(1, 2, 3); array_multisort($books, $sort_array);

В данном примере я произвёл сортировку простого одномерного массива $books в соответствии с массивом $sort_array. В результате первый массив принял следующий вид:

Array ( => 11 => 27 => 32)

А второй стал таким:

Array ( => 2 => 3 => 1)

То есть, он отсортировался в соответствии с первым. Вот такая вот петрушка 🙂

Более детально об array_multisort рассказано на следующем видео. Также там вы найдёте дополнительные примеры её использования:

С помощью данной функции также можно производить сортировку многомерных массивов:

$books = array(array(32), array(11), array(27)); $sort_array = array(1, 2, 3); array_multisort($books, $sort_array);

Массив $books будет выглядеть так:

Array ( => Array ( => 11) => Array ( => 27) => Array ( => 32))

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

Вот такой своеобразный «снежный ком» в php.

При сортировке массива php с помощью данной функции для ассоциативных массивов связь «ключ-значение» сохраняется, а для числовых – нет.

Программисты, которые производили тестирование работы различных функций, отмечают, что при сортировке многомерного массива php array_multisort показывает лучшие результаты, чем usort.

Но array_multisort не сможет справиться со всеми задачами, которые под силу usort. Например, та же сортировка многомерного массива php по необходимому полю . Так что в каждом отдельном случае нужно анализировать свои шансы на успех при использовании той либо другой конструкции.

Про себя я могу сказать, что я немного недолюбливаю array_multisort из-за её запутанности и повышенного мозгового напряжения, которым сопровождаются попытки представить итоговый массив, отсортированный с её помощью.

Поэтому я стараюсь не пользоваться ей без особой надобности, отдавая предпочтение usort и более простым функциям, к чему призываю и вас 🙂

Рассмотренные нами ранее функции позволяют производить сортировку массивов в php по значению элементов. Давайте поговорим о том, как можно произвести аналогичное действие по ключам элементов.

Функции php для сортировки массива по ключу

Перед тем, как мы перейдём к обзору функций данной группы я хотел бы сказать, что у всех них есть одна общая черта – все они сохраняют отношение «ключ-значение». А иначе, собственно говоря, и быть не могло, т.к. тогда от них не было бы смысла 🙂

Такая вот особенность. Рассмотрим каждую функцию поподробнее.

ksort($array, $flag); — функция является аналогом asort, только упорядочивание элементов в массиве будет происходить не по значениям, а по ключам.

В данной конструкции два входных параметра: сортируемый массив php и один из флагов сортировки, с полным перечнем которых вы можете ознакомиться в описании функции sort (использование его необязательно). Данная php функция позволяет отсортировать массив по возрастанию.

Для демонстрации его работы вернёмся к примеру, описанному в самом начале статьи:

Array ( => 11 => 18 => 9)

Если сделать его сортировку с помощью ksort, то в результате он примет следующий вид:

Array ( => 18 => 9 => 11)

Думаю, всё просто и понятно.

krsort($array, $flag); — ещё одна функция php для сортировки массива по ключу, очень похожая на предыдущую.

Единственное отличие заключается в том, что она производит сортировку массива php по убыванию. То есть, она является антагонистом ksort, как и rsort для sort.

У неё также два входных параметра: сортируемый массив и один из ключей. После её запуска наш пример примет вид:

Array ( => 11 => 9 => 18)

Думаю, комментарии излишни 🙂

ukrsort($array, ‘function’); — аналог упомянутой ранее функции php для сортировки массива по ключу — usort.

Работает по тому же принципу: сохраняет отношение «ключ-значение» и сортировка массива php производится в соответствии с пользовательской функцией, имя которой передаётся вторым параметром. Первый параметр неизменный – это сортируемый массив.

Отличие от usort заключается в том, что сортировка происходит по ключам элементов.

Для наглядности работы данной функции используем следующий пример:

Array ( => 40 => 0 => 10)

К примеру, нам нужно сделать сортировку массива php по ключу в порядке возрастания. В таком случае, пользовательская функция будет выглядеть так:

Function myCmp($a, $b) { if ($a == $b) return 0; return $a < $b ? 1: -1; }

В результате наш массив примет следующий вид:

Array ( => 0 => 10 => 40)

Однозначный плюс использования этой функции – то, что с её помощью можно делать сортировку массива php по какому-то необычному признаку или алгоритму.

Напоминаю, что использовать её нужно только в том случае, когда ключи элементов массива несут какую-то смысловую нагрузку. В противном же случае, лучше использовать usort или другие, более простые функции.

Вот наша статья и подошла к концу (лайк, если дочитал до этого места) 🙂

В ней я постарался максимально просто и в тоже время наглядно и полно описать все возможные способы сортировки различных видов массив в php, подкрепляя свои слова примерами.

Признаю, что публикация вышла довольно объёмной и трудной для единоразового чтения. Зато каждый раз, когда вам потребуется сортировка массива php , вы всегда сможете обратиться к данной статье за описанием требуемой вам функции и посмотреть примеры её использования.

Надеюсь, информация была для вас полезна 🙂

Подписывайтесь на обновления проекта и

Я хотел бы добавить свое собственное решение здесь, так как оно предлагает функции, которые другие ответы не имеют.

В частности, преимущества этого решения включают:

  • Он многоразовый : вы указываете столбец сортировки как переменную, а не hardcoding.
  • гибкий : вы можете указать несколько столбцов сортировки (сколько угодно) - дополнительные столбцы используются в качестве разделителей между элементами, которые первоначально сравнивают одинаковые.
  • обратимый : вы можете указать, что сортировка должна быть отменена - индивидуально для каждого столбца.
  • расширяемый : если в наборе данных содержатся столбцы, которые не могут быть сопоставлены "немым" способом (например, строками даты), вы также можете указать, как преобразовать эти элементы в значение, которое может быть напрямую (например, экземпляр DateTime).
  • ассоциативно, если вы хотите : этот код выполняет сортировку элементов, но вы выбираете фактическую функцию сортировки (usort или uasort).
  • Наконец, он не использует array_multisort: в то время как array_multisort удобно, это зависит от создания проекции всех ваших входных данных перед сортировкой. Это потребляет время и память и может быть просто запретительным, если ваш набор данных большой.

Код

function make_comparer() { // Normalize criteria up front so that the comparer finds everything tidy $criteria = func_get_args(); foreach ($criteria as $index => $criterion) { $criteria[$index] = is_array($criterion) ? array_pad($criterion, 3, null) : array($criterion, SORT_ASC, null); } return function($first, $second) use (&$criteria) { foreach ($criteria as $criterion) { // How will we compare this round? list($column, $sortOrder, $projection) = $criterion; $sortOrder = $sortOrder === SORT_DESC ? -1: 1; // If a projection was defined project the values now if ($projection) { $lhs = call_user_func($projection, $first[$column]); $rhs = call_user_func($projection, $second[$column]); } else { $lhs = $first[$column]; $rhs = $second[$column]; } // Do the actual comparison; do not return if equal if ($lhs < $rhs) { return -1 * $sortOrder; } else if ($lhs > $rhs) { return 1 * $sortOrder; } } return 0; // tiebreakers exhausted, so $first == $second }; }

Как использовать

$data = array(array("zz", "name" => "Jack", "number" => 22, "birthday" => "12/03/1980"), array("xx", "name" => "Adam", "number" => 16, "birthday" => "01/12/1979"), array("aa", "name" => "Paul", "number" => 16, "birthday" => "03/11/1987"), array("cc", "name" => "Helen", "number" => 44, "birthday" => "24/06/1967"),);

Основы

Функция make_comparer принимает переменное количество аргументов, которые определяют нужный тип, и возвращает функцию, которую вы должны использовать в качестве аргумента для usort или uasort .

Простейшим вариантом использования является передача ключа, который вы хотите использовать для сравнения элементов данных. Например, чтобы отсортировать $data с помощью элемента name , который вы делаете

Usort($data, make_comparer("name"));

Ключ может также быть числом, если элементы представляют собой числовые индексированные массивы. Для примера в вопросе это будет

Usort($data, make_comparer(0)); // 0 = first numerically indexed column

Несколько столбцов сортировки

Вы можете указать несколько столбцов сортировки, передав дополнительные параметры make_comparer . Например, для сортировки по "числу", а затем по столбцу с нулевой индексацией:

Usort($data, make_comparer("number", 0));

Расширенные функции

Дополнительные функции доступны, если вы укажете столбец сортировки как массив вместо простой строки. Этот массив должен быть численно проиндексирован и должен содержать следующие элементы:

0 => the column name to sort on (mandatory) 1 => either SORT_ASC or SORT_DESC (optional) 2 => a projection function (optional)

Посмотрим, как мы можем использовать эти функции.

Обратный сортировка

Сортировка по имени по убыванию:

Usort($data, make_comparer(["name", SORT_DESC]));

Для сортировки по убыванию номера, а затем по имени:

Usort($data, make_comparer(["number", SORT_DESC], ["name", SORT_DESC]));

Пользовательские прогнозы

В некоторых сценариях вам может понадобиться сортировать по столбцу, значения которого не позволяют хорошо сортировать. Столбец "День рождения" в наборе образцов данных соответствует этому описанию: нет смысла сравнивать дни рождения как строки (потому что "01/01/1980" предшествует "10/10/1970"). В этом случае мы хотим указать, как проецировать фактические данные в форму, которую можно напрямую сравнивать с желаемой семантикой.

Проекции могут быть указаны как любой тип callable : как строки, массивы или анонимные функции. Предполагается, что проекция принимает один аргумент и возвращает его проецируемую форму.

Следует отметить, что в то время как прогнозы похожи на пользовательские функции сравнения, используемые с usort и семейством, они проще (вам нужно только преобразовать одно значение в другое) и использовать все функции, уже запеченные в make_comparer .

Позвольте отсортировать набор данных примера без проекции и посмотреть, что произойдет:

Usort($data, make_comparer("birthday"));

Это не был желаемый результат. Но мы можем использовать date_create в качестве проекции:

Usort($data, make_comparer(["birthday", SORT_ASC, "date_create"]));

Это правильный порядок, который мы хотели.

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

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

Наконец, вот пример, который использует все функции: он сначала сортируется по убыванию числа, а по возрастанию по дням:

Usort($data, make_comparer(["number", SORT_DESC], ["birthday", SORT_ASC, "date_create"]));

Массивы очень удобны для обработки большого количества информации. Существует большое количество функций для удобной работы с ними. В частности, сегодня речь пойдёт о сортировке. Ничего нового открывать я не буду, просто познакомлю с самыми нужными для ежедневного кодинга.

Сортирование индексированных массивов: sort() and rsort()

Функция sort() сортирует значения в индексированном массиве в возрастающем порядке. Это означает, что A идёт перед Z, 0 -перед 9. Заглавные буквы перед строчными, буквы перед цифрами. Например:

$myArray = array(1, 2, "a", "b", "A", "B"); sort($myArray); // Отображает "A B a b 1 2" foreach ($myArray as $val) echo "$val ";

rsort() - это sort() наоборот:

$myArray = array(1, 2, "a", "b", "A", "B"); rsort($myArray); // Отображает "2 1 b a B A" foreach ($myArray as $val) echo "$val ";

Все sorting-функции возвращают true при успехе, и false при обломе)

Сортировка ассоциативных массивов: asort() and arsort()

sort() и rsort() очень хороши для индексированных массивов, где не нужно волноваться о связи ключа и значения. Могут получится неожиданности) Например:

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); sort($movie); // Отобразит "Array ( => Alfred Hitchcock => Rear Window => 112 => 1954)" print_r($movie);

Видно, что произошла путаница, и оригинальная структура «title», «director», «year» and «minutes» поменялась.

Если же вы хотите сортировать ассоциативный массив по первичному ключу, используйте функции asort() и arsort() Эти функции учитывают связь ключей и их значений

За возрастающий порядок сортировки отвечает функция asort():

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); asort($movie); // Отображает "Array ( => Alfred Hitchcock => Rear Window => 112 => 1954)" print_r($movie);

arsort() наоборот:

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); arsort($movie); // Отображает "Array ( => 1954 => 112 => Rear Window => Alfred Hitchcock)" print_r($movie);

Сортировка ассоциативных массивов по ключу: ksort() и krsort()

ksort() сортирует по возрастанию значения ключа, krsort() - по убыванию. Как и asort() с arsort(), эта функция сохраняет связь между ключом значением. Пример:

$movie = array("title" => "Rear Window", "director" => "Alfred Hitchcock", "year" => 1954, "minutes" => 112); // Отображает "Array ( => Alfred Hitchcock => 112 => Rear Window => 1954)" ksort($movie); print_r($movie); // Отображает "Array ( => 1954 => Rear Window => 112 => Alfred Hitchcock)" krsort($movie); print_r($movie);

Сортировка сложных и многомерных массивов с array_multisort()

Очень мощная функция array_multisort() может сортировать многомерный массив, сохраняя связь между массивами.
Вобщем, сейчас всё увидим:

Сортировка сложных массивов

Сортируем, используя array_multisort(), просто указываем те массивы, которые нужно обратотать:

$directors = array("Stanley Kubrick", "Alfred Hitchcock", "Martin Scorsese"); $titles = array("Full Metal Jacket", "Rear Window", "Mean Streets"); $years = array(1987, 1954, 1973); array_multisort($directors, $titles, $years); print_r($directors); echo "
"; print_r($titles); echo "
"; print_r($years); echo "
";

Этот код отобразит:

Array ( => Alfred Hitchcock => Martin Scorsese => Stanley Kubrick)
Array ( => Rear Window => Mean Streets => Full Metal Jacket)
Array ( => 1954 => 1973 => 1987)

Сначала array_multisort() сортирует значения в $directors в возрастающем порядке, затем 2 остальных так же.

А что если мы хотим сортировать, например, чтобы вначале «title»? Просто положите $titles вперёд списка:

Array_multisort($titles, $directors, $years);

Если первый массив содержит какое-то количество id-номеров, тогда array_multisort() сортирует
по этим значениям первый массив, затем - второй, и тд. Пример:

$directors = array("Stanley Kubrick", "Alfred Hitchcock", "Martin Scorsese", "Stanley Kubrick"); $titles = array("Full Metal Jacket", "Rear Window", "Mean Streets", "A Clockwork Orange"); $years = array(1987, 1954, 1973, 1971); array_multisort($directors, $titles, $years); print_r($directors); echo "
"; print_r($titles); echo "
"; print_r($years); echo "
";

Этот код выдаёт следующее - заметьте, что «A Clockwork Orange» перед «Full Metal Jacket»:

Array ( => Alfred Hitchcock => Martin Scorsese => Stanley Kubrick => Stanley Kubrick)
Array ( => Rear Window => Mean Streets => A Clockwork Orange => Full Metal Jacket)
Array ( => 1954 => 1973 => 1971 => 1987)

Меняем порядок сортировки

Вы можете пропустить (опционально) flag-аргумент после аргумента массива чтобы менять порядок сортировки:

SORT_ASC
сортировка по возрастанию
SORT_DESC
сортировка по убыванию

Тут сортируем $directors по возрастанию, затем $titles по убыванию:

$directors = array("Stanley Kubrick", "Alfred Hitchcock", "Martin Scorsese", "Stanley Kubrick"); $titles = array("Full Metal Jacket", "Rear Window", "Mean Streets", "A Clockwork Orange"); $years = array(1987, 1954, 1973, 1971); array_multisort($directors, SORT_ASC, $titles, SORT_DESC, $years); print_r($directors); echo "
"; print_r($titles); echo "
"; print_r($years); echo "
";

Вот что вышло: заметьте, что «Full Metal Jacket» теперь перед «A Clockwork Orange»:


Array ( => Alfred Hitchcock => Martin Scorsese => Stanley Kubrick => Stanley Kubrick)
Array ( => Rear Window => Mean Streets => Full Metal Jacket => A Clockwork Orange)
Array ( => 1954 => 1973 => 1987 => 1971)

Сортировка многомерных массивов

Сортировка через array_multisort() проходит по первому элементу каждого массива. Если 2 значения одинаковы, сортирвка идёт по 2у элементу и тп.

Это пример, который показывает, как это работает
Сортировка идет по director, потом по title, потом по year:

$movies = array(array("director" => "Alfred Hitchcock", "title" => "Rear Window", "year" => 1954), array("director" => "Stanley Kubrick", "title" => "Full Metal Jacket", "year" => 1987), array("director" => "Martin Scorsese", "title" => "Mean Streets", "year" => 1973), array("director" => "Stanley Kubrick", "title" => "A Clockwork Orange", "year" => 1971)); array_multisort($movies); echo "

"; print_r($movies); echo "
";

Результат:


Array
=> Array
=> Alfred Hitchcock
=> Rear Window
=> 1954
)

=> Array
=> Martin Scorsese
=> Mean Streets
=> 1973
)

=> Array
=> Stanley Kubrick
=> A Clockwork Orange
=> 1971
)

=> Array
=> Stanley Kubrick
=> Full Metal Jacket
=> 1987
)

Как видите, array_multisort() отсортирвал массив по director. Когда имя режиссёра повторилось, («Stanley Kubrick»), сортировка пошла по title.

Чтобы отсортровать в обратном порядке, укажите SORT_DESC-флаг как второй аргумент array_multisort(). Просто!

Итог

В этом уроке мы посмотрели на простые PHP-функции для сортровки массива:

* sort() и rsort() для сортровки индексируемых массивов
* asort() и arsort() для сортровки асоциативных массивов
* ksort() и krsort() для сортровки ассоциативнх массивов по ключу
* array_multisort() для сортировки для сортировки сложных и многомерных массивов

PHP-сортировка массивов очень мощна и проста, можно сортировать быстро и как угодно). ТОлько тут мы изучили аж 13 функций! Чтобы увидеть больше, смотрите

Наткнулся тут на интересный блог – блог про блоги так сказать) Автор обзоры делает)

Подпишись на каталога блога

» »

Лучшие статьи по теме