Natsort: примеры (PHP)
natsort(array &$array): boolФункция natsort() в PHP производит сортировку массива, используя алгоритм "естественной сортировки" (natural ordering). В отличие от стандартных алгоритмов, которые сравнивают строки побайтово, естественная сортировка распознает числовые последовательности внутри строк и упорядочивает их по человеческому восприятию.
Функция применяется для сортировки массивов, содержащих строки с числами, например, названия файлов (img1.jpg, img10.jpg, img2.jpg) или версий программ (v1.0.1, v1.0.10). Стандартная сортировка расположила бы img10.jpg перед img2.jpg, так как символ '1' идет раньше '2'. natsort() решает эту проблему.
Функция принимает один обязательный параметр:
- array &$array (передается по ссылке) – массив, который необходимо отсортировать. После выполнения функции исходный массив изменяется. Функция возвращает
trueв случае успеха иfalseпри возникновении ошибки.
Базовое применение для сортировки простого массива строк с числами.
<?php
$files = ["img12.png", "img10.png", "img2.png", "img1.png"];
natsort($files);
print_r($files);
?>Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)
Функция сохраняет связь ключ-значение (ассоциативные индексы).
<?php
$versions = ["v1.0.2", "v1.0.1", "v1.0.10", "v1.0.0"];
$arrayCopy = $versions;
natsort($arrayCopy);
print_r($arrayCopy);
?>Array
(
[3] => v1.0.0
[1] => v1.0.1
[0] => v1.0.2
[2] => v1.0.10
)
- sort() / rsort() – стандартная сортировка по возрастанию/убыванию. Не сохраняет ключи. Не подходит для "естественного" упорядочивания.
- asort() / arsort() – сортирует по значению, сохраняя связь с ключом. Использует стандартное сравнение.
- natcasesort() – выполняет естественную сортировку без учета регистра символов. Аналог
natsort(), но регистронезависимый. - usort() – сортирует массив по пользовательской функции сравнения. Дает полный контроль над логикой сортировки, но требует написания callback-функции.
Функцию natsort() предпочтительнее использовать для сортировки строк, содержащих числовые данные, где важен человекочитаемый порядок. Для регистронезависимой естественной сортировки применяют natcasesort().
<?php
$var = "строка";
natsort($var); // Вызовет предупреждение
?>Warning: natsort() expects parameter 1 to be array, string given
Функция сохраняет ключи. Если необходим сброс индексов, результат нужно передать в array_values().
<?php
$arr = [10 => "img2", 0 => "img10"];
natsort($arr);
print_r($arr);
print_r(array_values($arr));
?>Array
(
[10] => img2
[0] => img10
)
Array
(
[0] => img2
[1] => img10
)
При наличии элементов разных типов (числа, строки, массивы) поведение может быть неочевидным из-за внутреннего приведения типов в PHP.
В PHP 8.0 и 8.1 не было специфических изменений для функции natsort(). Однако общие изменения в механизмах сравнения и сортировки в PHP 8.0 (например, более строгое отношение к типам) могут косвенно влиять на поведение при наличии в массиве элементов разных типов. В частности, сравнение строк с числами и другими типами стало более предсказуемым.
Для сортировки массива по ключам в естественном порядке можно использовать комбинацию uksort() и функции сравнения strnatcmp().
<?php
$data = ["item-2" => "B", "item-10" => "A", "item-1" => "C"];
uksort($data, 'strnatcmp');
print_r($data);
?>Array
(
[item-1] => C
[item-2] => B
[item-10] => A
)
natsort() не учитывает локаль. Для сортировки строк с учетом языковых правил и естественного порядка чисел можно попробовать комбинацию функций.
<?php
$releases = ["product-1.0.2", "product-1.10.0", "product-1.2.1"];
natsort($releases);
print_r($releases);
?>Array
(
[0] => product-1.0.2
[2] => product-1.2.1
[1] => product-1.10.0
)
Для сортировки массива объектов по строковому свойству можно использовать usort() с strnatcmp().
<?php
class Item {
public $name;
public function __construct($name) { $this->name = $name; }
}
$items = [new Item("img2"), new Item("img10"), new Item("img1")];
usort($items, fn($a, $b) => strnatcmp($a->name, $b->name));
print_r(array_map(fn($it) => $it->name, $items));
?>Array
(
[0] => img1
[1] => img2
[2] => img10
)
Natsort в Python
Используют функцию sorted() с ключом key из модуля natsort или re для извлечения чисел.
from natsort import natsorted
files = ["img12.png", "img10.png", "img2.png", "img1.png"]
print(natsorted(files))['img1.png', 'img2.png', 'img10.png', 'img12.png']
Natsort в Javascript
В JavaScript нет встроенной функции. Используют метод Array.prototype.sort() с пользовательской функцией сравнения или библиотеки типа natural-compare.
let files = ["img12.png", "img10.png", "img2.png", "img1.png"];
files.sort( (a, b) => a.localeCompare(b, undefined, {numeric: true, sensitivity: 'base'}));
console.log(files);['img1.png', 'img2.png', 'img10.png', 'img12.png']
Natsort в MySQL
При ORDER BY по строковому полю, содержащему числа, также происходит лексикографическая сортировка. Для естественной сортировки данные часто приводят к нужному виду на этапе проектирования или используют функции типа CAST для извлечения чисел.