Сортировка массивов
В PHP есть несколько функций для сортировки массивов, на этой странице даётся их общее описание.
Основные различия между функциями:
- В одних функциях массивы ( array ) сортируются по ключам элементов, в других по значениям: $array[‘ключ’] = ‘значение’;
- В каких-то функциях связь между ключами и значениями после сортировки сохраняется, в каких-то нет. Это может приводить к тому, что ключи будут сбрасываться в числовые значения (0, 1, 2, . ).
- Различия в порядке сортировки: алфавитный, возрастающий, убывающий, числовой, естественный, случайный или определённый пользователем
- Примечание: Все функции сортировки модифицируют переданный массив, а не возвращают отсортированную копию
- Если какая-либо из этих функций сортировки оценивает два элемента как равные, они сохраняют свой исходный порядок. До PHP 8.0.0 их порядок не был определён (сортировка была нестабильной).
| Имя функции | Сортирует по | Сохраняет связь ключ — значение | Порядок сортировки | Похожие функции |
|---|---|---|---|---|
| array_multisort() | значению | строковые ( string ) ключи да, числовые ( int ) — нет | первый массив или настройки сортировки | array_walk() |
| asort() | значению | да | по возрастанию | arsort() |
| arsort() | значению | да | по убыванию | asort() |
| krsort() | ключу | да | по убыванию | ksort() |
| ksort() | ключу | да | по возрастанию | krsort() |
| natcasesort() | значению | да | естественный, нечувствительный к регистру | natsort() |
| natsort() | значению | да | естественный | natcasesort() |
| rsort() | значению | нет | по убыванию | sort() |
| shuffle() | значению | нет | случайный | array_rand() |
| sort() | значению | нет | по возрастанию | rsort() |
| uasort() | значению | да | определяется пользователем | uksort() |
| uksort() | ключу | да | определяется пользователем | uasort() |
| usort() | значению | нет | определяется пользователем | uasort() |
User Contributed Notes 2 notes
10 years ago
While this may seem obvious, user-defined array sorting functions ( uksort(), uasort(), usort() ) will *not* be called if the array does not have *at least two values in it*.
The following code:
function usortTest ( $a , $b ) var_dump ( $a );
var_dump ( $b );
return — 1 ;
>
$test = array( ‘val1’ );
usort ( $test , «usortTest» );
$test2 = array( ‘val2’ , ‘val3’ );
usort ( $test2 , «usortTest» );
string(4) «val3»
string(4) «val2»
The first array doesn’t get sent to the function.
Please, under no circumstance, place any logic that modifies values, or applies non-sorting business logic in these functions as they will not always be executed.
12 years ago
Another way to do a case case-insensitive sort by key would simply be:
uksort ( $array , ‘strcasecmp’ );
?>
Since strcasecmp is already predefined in php it saves you the trouble to actually write the comparison function yourself.
- Массивы
- Введение
- Установка и настройка
- Предопределённые константы
- Сортировка массивов
- Функции для работы с массивами
- Copyright © 2001-2024 The PHP Group
- My PHP.net
- Contact
- Other PHP.net sites
- Privacy policy
Сортировка по убыванию
Сразу оговорюсь, я новичок в программирование и пока что знаниями в теории алгоритмов похвастаться не могу. Сегодня решал задачу сортировки массива состоящего из целочисленных элементов, который должен упорядочить в порядке убывания . Скажу честно, было тяжеловато решать эту проблему, пошел на принцип и не гуглил решение этой задачи. Что-то я написал, был близок, но все-таки чего-то не хватало. Решил погуглить и нашёл решение этой проблемы, удовлетворился тем, что мой код был схож с решением. Привожу код:
for (int j = 0; j < intArray.length; j++) for (int k = 0; k < intArray.length - 1; k++) < if (intArray[k] < intArray[k + 1]) < temp = intArray[k]; intArray[k] = intArray[k + 1]; intArray[k + 1] = temp; >>Разберём пример. Допустим у нас есть массив целочисленных элементов (3, 2, 5, 1). После сортировки мы получим (5, 3, 2, 1). Пошагово это будет выглядеть так:
j = 0; k = 0; (3 < 2) -->false --> 3 2 5 1 k = 1; (2 < 5) -->true --> 3 5 2 1 k = 2; (2 < 1) -->false --> 3 5 2 1 j = 1; k = 0; (3 < 5) -->true --> 5 3 2 1 k = 1; (3 < 2) -->false --> 5 3 2 1 k = 2; (2 < 1) -->false --> 5 3 2 1После второй итерации внешнего цикла, у нас уже есть готовый ответ, это достаточно для этого примера, но не для всех. Вопрос в следующем, почему внешний цикл должен управляться именно этим условием (j < intArray.length) ? Как понять, что для полного успеха, нужно именно такое условие? Просто хочется понять этот алгоритм изнутри. Спасибо за внимание.
Array.prototype.sort()
Метод sort() на месте сортирует элементы массива и возвращает отсортированный массив. Сортировка не обязательно устойчива (англ.). Порядок сортировки по умолчанию соответствует порядку кодовых точек Unicode.
Синтаксис
arr.sort([compareFunction])
Параметры
Необязательный параметр. Указывает функцию, определяющую порядок сортировки. Если опущен, массив сортируется в соответствии со значениями кодовых точек каждого символа Unicode, полученных путём преобразования каждого элемента в строку.
Возвращаемое значение
Отсортированный массив. Важно, что копия массива не создаётся — массив сортируется на месте.
Описание
Если функция сравнения compareFunction не предоставляется, элементы сортируются путём преобразования их в строки и сравнения строк в порядке следования кодовых точек Unicode. Например, слово «Вишня» идёт перед словом «бананы». При числовой сортировке, 9 идёт перед 80, но поскольку числа преобразуются в строки, то «80» идёт перед «9» в соответствии с порядком в Unicode.
var fruit = ["арбузы", "бананы", "Вишня"]; fruit.sort(); // ['Вишня', 'арбузы', 'бананы'] var scores = [1, 2, 10, 21]; scores.sort(); // [1, 10, 2, 21] var things = ["слово", "Слово", "1 Слово", "2 Слова"]; things.sort(); // ['1 Слово', '2 Слова', 'Слово', 'слово'] // В Unicode, числа находятся перед буквами в верхнем регистре, // а те, в свою очередь, перед буквами в нижнем регистре.
Если функция сравнения compareFunction предоставлена, элементы массива сортируются в соответствии с её возвращаемым значением. Если сравниваются два элемента a и b , то:
- Если compareFunction(a, b) меньше 0, сортировка поставит a по меньшему индексу, чем b , то есть, a идёт первым.
- Если compareFunction(a, b) вернёт 0, сортировка оставит a и b неизменными по отношению друг к другу, но отсортирует их по отношению ко всем другим элементам. Обратите внимание: стандарт ECMAscript не гарантирует данное поведение, и ему следуют не все браузеры (например, версии Mozilla по крайней мере, до 2003 года).
- Если compareFunction(a, b) больше 0, сортировка поставит b по меньшему индексу, чем a .
- Функция compareFunction(a, b) должна всегда возвращать одинаковое значение для определённой пары элементов a и b . Если будут возвращаться непоследовательные результаты, порядок сортировки будет не определён.
Итак, функция сравнения имеет следующую форму:
function compare(a, b) if (a меньше b по некоторому критерию сортировки) return -1; > if (a больше b по некоторому критерию сортировки) return 1; > // a должно быть равным b return 0; >
Для числового сравнения, вместо строкового, функция сравнения может просто вычитать b из a . Следующая функция будет сортировать массив по возрастанию:
function compareNumbers(a, b) return a - b; >
Метод sort можно удобно использовать с функциональными выражениями (и замыканиями):
var numbers = [4, 2, 5, 1, 3]; numbers.sort(function (a, b) return a - b; >); console.log(numbers); // [1, 2, 3, 4, 5]
Объекты могут быть отсортированы по значению одного из своих свойств.
var items = [ name: "Edward", value: 21 >, name: "Sharpe", value: 37 >, name: "And", value: 45 >, name: "The", value: -12 >, name: "Magnetic" >, name: "Zeros", value: 37 >, ]; items.sort(function (a, b) if (a.name > b.name) return 1; > if (a.name b.name) return -1; > // a должно быть равным b return 0; >);
Примеры
Пример: создание, отображение и сортировка массива
В следующем примере создаётся четыре массива, сначала отображается первоначальный массив, а затем они сортируются. Числовые массивы сортируются сначала без, а потом с функцией сравнения.
var stringArray = ["Голубая", "Горбатая", "Белуга"]; var numericStringArray = ["80", "9", "700"]; var numberArray = [40, 1, 5, 200]; var mixedNumericArray = ["80", "9", "700", 40, 1, 5, 200]; function compareNumbers(a, b) return a - b; > // снова предполагаем, что функция печати определена console.log("stringArray:", stringArray.join()); console.log("Сортировка:", stringArray.sort()); console.log("numberArray:", numberArray.join()); console.log("Сортировка без функции сравнения:", numberArray.sort()); console.log( "Сортировка с функцией compareNumbers:", numberArray.sort(compareNumbers), ); console.log("numericStringArray:", numericStringArray.join()); console.log("Сортировка без функции сравнения:", numericStringArray.sort()); console.log( "Сортировка с функцией compareNumbers:", numericStringArray.sort(compareNumbers), ); console.log("mixedNumericArray:", mixedNumericArray.join()); console.log("Сортировка без функции сравнения:", mixedNumericArray.sort()); console.log( "Сортировка с функцией compareNumbers:", mixedNumericArray.sort(compareNumbers), );
Этот пример произведёт следующий вывод. Как показывает вывод, когда используется функция сравнения, числа сортируются корректно вне зависимости от того, являются ли они собственно числами или строками с числами.
stringArray: Голубая,Горбатая,Белуга Сортировка: Белуга,Голубая,Горбатая numberArray: 40,1,5,200 Сортировка без функции сравнения: 1,200,40,5 Сортировка с функцией compareNumbers: 1,5,40,200 numericStringArray: 80,9,700 Сортировка без функции сравнения: 700,80,9 Сортировка с функцией compareNumbers: 9,80,700 mixedNumericArray: 80,9,700,40,1,5,200 Сортировка без функции сравнения: 1,200,40,5,700,80,9 Сортировка с функцией compareNumbers: 1,5,9,40,80,200,700
Пример: сортировка не-ASCII символов
Для сортировки строк с не-ASCII символами, то есть строк с символами акцента (e, é, è, a, ä и т.д.), строк, с языками, отличными от английского: используйте String.localeCompare . Эта функция может сравнивать эти символы, чтобы они становились в правильном порядке.
var items = ["réservé", "premier", "cliché", "communiqué", "café", "adieu"]; items.sort(function (a, b) return a.localeCompare(b); >); // items равен ['adieu', 'café', 'cliché', 'communiqué', 'premier', 'réservé']
Пример: сортировка c помощью map
Функция сравнения (compareFunction) может вызываться несколько раз для каждого элемента в массиве. В зависимости от природы функции сравнения, это может привести к высоким расходам ресурсов. Чем более сложна функция сравнения и чем больше элементов требуется отсортировать, тем разумнее использовать map для сортировки. Идея состоит в том, чтобы обойти массив один раз, чтобы извлечь фактические значения, используемые для сортировки, во временный массив, отсортировать временный массив, а затем обойти временный массив для получения правильного порядка.
// массив для сортировки var list = ["Дельта", "альфа", "ЧАРЛИ", "браво"]; // временный массив содержит объекты с позицией и значением сортировки var mapped = list.map(function (el, i) return index: i, value: el.toLowerCase() >; >); // сортируем массив, содержащий уменьшенные значения mapped.sort(function (a, b) if (a.value > b.value) return 1; > if (a.value b.value) return -1; > return 0; >); // контейнер для результа var result = mapped.map(function (el) return list[el.index]; >);
Спецификации
Specification ECMAScript Language Specification
# sec-array.prototype.sortСовместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Array.prototype.reverse()
- String.prototype.localeCompare()
Как сделать быструю сортировка массива на javascript
Быстрая сортировка, часто называемая qsort, один из самых быстрых известных универсальных алгоритмов сортировки массивов: в среднем имеет сложность O(n\log n) обменов при упорядочении n элементов. Из-за наличия ряда недостатков на практике обычно используется с некоторыми доработками. Не углубляясь в подробности рассмотрим простой вариант использующий рекурсию.
Алгоритм:
- Выбрать из массива элемент, называемый опорным. Это может быть любой из элементов массива.
- Сравнить все остальные элементы с опорным и переставить их в массиве так, чтобы разбить массив на три непрерывных отрезка, следующих друг за другом: «элементы меньшие опорного», «равные» и «большие».
- Для отрезков «меньших» и «больших» значений выполнить рекурсивно ту же последовательность операций, если длина отрезка больше единицы.
Реализация:
const quickSort = (arr) => // Условие остановки, выхода из рекурсии, возвращем массив с 1 элементом if (arr.length 2) return arr; // Выбираем опорный элемент let pivot = arr[0]; // Определяем массивы для тех, что меньше и больше опорного const left = []; const right = []; // Проходим циклом по всем элементам из массива и разносим их в массивы созданные ранее согласно условию, больше опорного - в правый, меньше - в левый for (let i = 1; i arr.length; i++) if (pivot > arr[i]) left.push(arr[i]); > else right.push(arr[i]); > > // Рекурсивно повторяем процесс для новых двух массивов, текущий опорный элемент - кладем как первый в правый массив. return quickSort(left).concat(pivot, quickSort(right)); >05 апреля 2023
Для примера быстрой сортировки числового массива numbers можно использовать встроенный метод Array.prototype.sort() . Этот метод сортирует элементы массива в порядке возрастания или по алфавиту, если элементы являются строками. Однако, если нужно отсортировать массив в порядке убывания или по другому критерию, то можно передать в метод sort() функцию сравнения.
Пример сортировки массива чисел в порядке возрастания:
const numbers = [5, 2, 8, 1, 4]; numbers.sort((a, b) => a - b); console.log(numbers); // [1, 2, 4, 5, 8]Пример сортировки массива строк в порядке убывания:
const fruits = ['banana', 'apple', 'orange', 'kiwi']; fruits.sort((a, b) => b.localeCompare(a)); console.log(fruits); // ['orange', 'kiwi', 'banana', 'apple']