Natcasesort: примеры (PHP)

Сортировка массивов функцией natcasesort в PHP
Раздел: Работа с массивами
natcasesort(array &$array): bool

Функция natcasesort() выполняет сортировку массива, используя алгоритм "natural order" (естественный порядок), без учета регистра символов. Эта функция полезна при работе со строками, которые содержат числа, например, именами файлов.

Принцип работы

Функция принимает один аргумент — массив, передаваемый по ссылке. Сортировка происходит по значениям массива, а ключи сохраняются. Функция возвращает true в случае успеха и false при ошибке.

Аргументы функции
  • array &$array — обязательный аргумент. Сортируемый массив, передаваемый по ссылке.
Базовые примеры использования
Сортировка списка файлов

Следующий код демонстрирует сортировку массива, содержащего имена файлов.

$files = [
    "img12.png",
    "img10.png",
    "Img2.png",
    "img1.png"
];
natcasesort($files);
print_r($files);
Array
(
    [3] => img1.png
    [2] => Img2.png
    [1] => img10.png
    [0] => img12.png
)
Сравнение с обычной сортировкой

Для сравнения используется функция sort().

$array = ["Item1", "item10", "item2", "ITEM20"];
$array_for_sort = $array;

sort($array_for_sort);
echo "sort(): ";
print_r($array_for_sort);

echo "\nnatcasesort(): ";
natcasesort($array);
print_r($array);
sort():
Array
(
    [0] => ITEM20
    [1] => Item1
    [2] => item10
    [3] => item2
)
natcasesort():
Array
(
    [0] => Item1
    [2] => item2
    [1] => item10
    [3] => ITEM20
)
Похожие функции в PHP
  • natsort() — выполняет сортировку в естественном порядке, но с учетом регистра символов. Используется, когда регистр имеет значение.
  • sort() — стандартная сортировка по значениям, ключи сбрасываются. Не подходит для строк с числами в "человеческом" формате.
  • asort() — сортирует массив по значениям, сохраняя связь ключей, но не использует естественный порядок.
  • usort() — сортировка с помощью пользовательской функции сравнения. Применяется для сложных критериев сортировки.

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

Типичные ошибки
Попытка сортировки не массива

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

$result = natcasesort("not an array");
Warning: natcasesort() expects parameter 1 to be array, string given...
Игнорирование возвращаемого значения

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

$arr = ["z", "a"];
$sorted = natcasesort($arr); // $sorted содержит true/false, а не массив
echo $sorted; // выведет 1 (true), а не массив
Смешанные типы данных в массиве

При наличии элементов разных типов результат может быть неочевидным.

$array = ["10", 2, "1"];
natcasesort($array);
print_r($array);
Array
(
    [2] => 1
    [1] => 2
    [0] => 10
) 
// Числа сравниваются как числа, а не строки с числами.
Изменения в последних версиях PHP

В PHP 8.0 поведение функции natcasesort() при сортировке массивов со смешанными типами стало более предсказуемым и согласованным. Ранее внутреннее сравнение элементов могло приводить к неожиданным результатам. Теперь стандартизированный алгоритм сравнения типов делает результат более стабильным, особенно когда массив содержит не только строки.

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

Расширенные примеры использования
Сортировка многомерного массива по значению поля

Хотя natcasesort() работает с одномерными массивами, ее можно использовать в комбинации с usort().

Пример php
$products = [
    ['name' => "Product 10", 'id' => 1],
    ['name' => "product 2", 'id' => 2],
    ['name' => "PRODUCT 1", 'id' => 3],
];

usort($products, function($a, $b) {
    return strnatcasecmp($a['name'], $b['name']);
});

print_r($products);
Array
(
    [0] => Array
        (
            [name] => PRODUCT 1
            [id] => 3
        )
    [1] => Array
        (
            [name] => product 2
            [id] => 2
        )
    [2] => Array
        (
            [name] => Product 10
            [id] => 1
        )
)
Сохранение ключей при сортировке ассоциативного массива

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

Пример php
$inventory = [
    "BOX-100" => 5,
    "box-1" => 10,
    "Box-15" => 7,
];
natcasesort($inventory); // Сортировка по ключам? Нет! Сортировка по значениям.
// Для сортировки по ключам нужно использовать uksort() с strnatcasecmp
uksort($inventory, 'strnatcasecmp');
print_r($inventory);
Array
(
    [box-1] => 10
    [Box-15] => 7
    [BOX-100] => 5
)
Работа с локалями и специальными символами

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

Пример php
$words = ["école", "Ecole", "écosse", "10 étoiles"];
natcasesort($words);
print_r($words);
// Сравним с локале-зависимой сортировкой
setlocale(LC_COLLATE, 'fr_FR.utf8');
$words2 = $words;
usort($words2, 'strcoll');
print_r($words2);
// natcasesort (обычно):
Array
(
    [1] => Ecole
    [0] => école
    [2] => écosse
    [3] => 10 étoiles
)
// strcoll с французской локалью может дать другой порядок для символов с диакритикой.
Аналоги в других языках программирования

Natcasesort в Python

В Python используется комбинация функций sorted() и метода str.casefold() с ключом сортировки.

import re
def natural_sort_key(s):
    return [int(text) if text.isdigit() else text.casefold() for text in re.split(r'(\d+)', s)]

files = ["img12.png", "img10.png", "Img2.png", "img1.png"]
sorted_files = sorted(files, key=natural_sort_key)
print(sorted_files)
['img1.png', 'Img2.png', 'img10.png', 'img12.png']

Natcasesort в Javascript

В JavaScript нет встроенной функции, поэтому часто используют метод sort() с пользовательской функцией сравнения.

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']

Natcasesort в MySQL

В запросах ORDER BY не поддерживает естественную сортировку из коробки. Для простых случаев можно использовать приведение типа.

-- Пример неполный, так как требует хитрых запросов или функций
SELECT name FROM files ORDER BY LOWER(name); -- Только без учета регистра

PHP natcasesort function comments

En
Natcasesort Sort an array using a case insensitive "natural order" algorithm