Avatar ·

Как отсортировать двумерный массив по значению одного из столбцов в PHP?

Привет, коллеги! Я только начал изучать PHP и столкнулся с проблемой, которая кажется простой, но я никак не могу её решить. У меня есть двумерный массив, который содержит данные о пользователях: имя, возраст и город. Вот как он выглядит: ```php $users = [ ['name' => 'Иван', 'age' => 25, 'city' => 'Москва'], ['name' => 'Мария', 'age' => 30, 'city' => 'Санкт-Петербург'], ['name' => 'Алексей', 'age' => 22, 'city' => 'Казань'], ['name' => 'Елена', 'age' => 28, 'city' => 'Новосибирск'] ]; ``` Мне нужно отсортировать этот массив по возрасту (по ключу 'age') в порядке возрастания, чтобы сначала шли самые молодые пользователи. Я пробовал использовать функцию `sort()`, но она полностью ломает структуру массива и теряет ключи. Пробовал `ksort()` и `asort()` — они работают только с одномерными массивами. В интернете видел что-то про `usort()`, но не понял, как её применить к вложенным массивам. Подскажите, пожалуйста, как правильно отсортировать такой массив? Мне нужно, чтобы после сортировки массив выглядел так: ```php [ ['name' => 'Алексей', 'age' => 22, 'city' => 'Казань'], ['name' => 'Иван', 'age' => 25, 'city' => 'Москва'], ['name' => 'Елена', 'age' => 28, 'city' => 'Новосибирск'], ['name' => 'Мария', 'age' => 30, 'city' => 'Санкт-Петербург'] ] ``` Буду очень благодарен за понятное объяснение с примерами кода! <<>>

Использование функции usort() для сортировки двумерных массивов

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

Вот как это работает:

<?php
$users = [
    ['name' => 'Иван', 'age' => 25, 'city' => 'Москва'],
    ['name' => 'Мария', 'age' => 30, 'city' => 'Санкт-Петербург'],
    ['name' => 'Алексей', 'age' => 22, 'city' => 'Казань'],
    ['name' => 'Елена', 'age' => 28, 'city' => 'Новосибирск']
];

// Сортировка по возрасту (по возрастанию)
usort($users, function($a, $b) {
    return $a['age'] - $b['age'];
});

print_r($users);
?>

Результат:

Array
(
    [0] => Array ([name] => Алексей [age] => 22 [city] => Казань)
    [1] => Array ([name] => Иван [age] => 25 [city] => Москва)
    [2] => Array ([name] => Елена [age] => 28 [city] => Новосибирск)
    [3] => Array ([name] => Мария [age] => 30 [city] => Санкт-Петербург)
)

Как это работает?

  • usort() принимает два параметра: массив для сортировки и callback-функцию.
  • Callback-функция получает два элемента массива ($a и $b) и должна вернуть:
    • Отрицательное число, если $a должен быть перед $b
    • Ноль, если они равны
    • Положительное число, если $b должен быть перед $a
  • Выражение $a['age'] - $b['age'] даёт отрицательное значение, если возраст в $a меньше, положительное — если больше, и ноль при равенстве.

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

Чтобы отсортировать по убыванию (от старших к младшим), просто поменяйте операнды местами:

usort($users, function($a, $b) {
    return $b['age'] - $a['age'];
});

Сортировка по строковым значениям

Для сортировки по имени (строковому полю) используйте strcmp():

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

Сортировка с сохранением ключей

Если вам нужно сохранить исходные ключи массива (не числовые), используйте uasort() вместо usort():

$users = [
    'user1' => ['name' => 'Иван', 'age' => 25],
    'user2' => ['name' => 'Мария', 'age' => 30]
];

uasort($users, function($a, $b) {
    return $a['age'] - $b['age'];
});

// Ключи 'user1' и 'user2' сохранятся

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

Можно сортировать сначала по одному полю, а при равенстве — по другому:

usort($users, function($a, $b) {
    // Сначала по возрасту
    $ageDiff = $a['age'] - $b['age'];
    if ($ageDiff !== 0) {
        return $ageDiff;
    }
    // Если возраст одинаковый, сортируем по имени
    return strcmp($a['name'], $b['name']);
});

Этот подход универсален и работает для любых типов данных. Главное — правильно написать функцию сравнения, и вы сможете сортировать массивы любой вложенности.

<<>>

Альтернативный подход: использование array_multisort()

Если вам неудобно писать callback-функции, можно воспользоваться array_multisort(). Этот метод требует предварительного извлечения столбца для сортировки:

<?php
$users = [
    ['name' => 'Иван', 'age' => 25, 'city' => 'Москва'],
    ['name' => 'Мария', 'age' => 30, 'city' => 'Санкт-Петербург'],
    ['name' => 'Алексей', 'age' => 22, 'city' => 'Казань'],
    ['name' => 'Елена', 'age' => 28, 'city' => 'Новосибирск']
];

// Извлекаем столбец 'age'
$ages = array_column($users, 'age');

// Сортируем исходный массив по извлечённому столбцу
array_multisort($ages, SORT_ASC, $users);

print_r($users);
?>

Плюсы и минусы

  • Плюсы: Код более читаемый для простых случаев, не нужно писать callback.
  • Минусы: Требуется дополнительная переменная, менее гибкий при сложных условиях сортировки (например, по нескольким полям с разными направлениями).

Для сортировки по убыванию замените SORT_ASC на SORT_DESC. Этот метод особенно удобен, когда нужно отсортировать несколько массивов синхронно (например, массив имён и массив возрастов).