Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Сортировка массивов

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

sort и rsort

sort() сортирует по возрастанию, rsort() — по убыванию:

<?php
 
$numbers = [3, 1, 2];
 
sort($numbers);
echo implode(', ', $numbers), "\n"; // 1, 2, 3
 
rsort($numbers);
echo implode(', ', $numbers); // 3, 2, 1

Строки сортируются по алфавиту.

Сохранение ключей

sort() нумерует элементы заново. Для ассоциативных массивов это не подходит: ключи потеряются. asort() сортирует по значениям и сохраняет ключи:

<?php
 
$prices = ['чай' => 250, 'сок' => 180, 'кофе' => 400];
 
asort($prices);
 
echo implode(', ', array_keys($prices)); // сок, чай, кофе

Парная функция arsort() сортирует по убыванию.

Сортировка по ключам

ksort() упорядочивает массив по ключам:

<?php
 
$stock = ['pear' => 5, 'apple' => 12, 'plum' => 3];
 
ksort($stock);
 
echo implode(', ', array_keys($stock)); // apple, pear, plum

Своё правило

usort() принимает функцию сравнения двух элементов. Она возвращает отрицательное число, если первый элемент должен идти раньше, положительное — если позже, и ноль — если они равны:

<?php
 
$users = [
    ['name' => 'Олег', 'age' => 31],
    ['name' => 'Анна', 'age' => 25],
];
 
usort($users, fn ($a, $b) => $a['age'] <=> $b['age']);
 
echo implode(', ', array_column($users, 'name')); // Анна, Олег

Оператор «космический корабль»

Оператор <=> сравнивает два значения и возвращает -1, 0 или 1 — ровно то, что нужно функции сравнения:

<?php
 
echo 1 <=> 2, "\n"; // -1
echo 2 <=> 2, "\n"; // 0
echo 3 <=> 2;       // 1

Чтобы отсортировать по убыванию, поменяйте аргументы местами: $b['age'] <=> $a['age'].

Сортировка по нескольким полям

Массивы сравниваются поэлементно, поэтому несколько полей можно сравнить за раз:

<?php
 
$users = [
    ['name' => 'Олег', 'age' => 25],
    ['name' => 'Анна', 'age' => 31],
    ['name' => 'Анна', 'age' => 25],
];
 
usort($users, fn ($a, $b) => [$a['name'], $a['age']] <=> [$b['name'], $b['age']]);
 
echo implode(' ', array_map(fn ($user) => $user['name'] . $user['age'], $users));

Выведется «Анна25 Анна31 Олег25»: сначала по имени, при равных именах — по возрасту.

Частая ошибка

Функции сортировки возвращают true, а не отсортированный массив. Присваивать их результат не нужно:

<?php
 
$numbers = [3, 1, 2];
 
// Неправильно: $numbers = sort($numbers); — в переменной окажется true
 
sort($numbers);
 
echo implode(', ', $numbers); // 1, 2, 3

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.