PHP сортировка многомерного ассоциативного массива по полю

/ 👁 1225

Раннее я уже писала статью о сортировке массивов в php, в том числе ассоциативных.

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

Допустим у нас есть многомерный ассоциативный массив, который мы хотим сортировать.

 

 $data = [
    ['id' => 7, 'age' => 47],
    ['id' => 3, 'age' => 32],
    ['id' => 5, 'age' => 58],
    ['id' => 1, 'age' => 23]
];

Мы можем хотеть сортировать его либо по полю id, либо по полю age. При этом мы можем хотеть сортировать либо в порядке увеличения, либо в порядке уменьшения значения.

Давайте напишем функцию сортировки.

 

function my_sort($arr, $field, $order){
    usort($arr, custom_sorter($field));
    if($order == 'desc'){
        return array_reverse($arr);
    }
    return $arr;
}

Функция my-sort принимает в качестве параметров:

  • массив, который будем сортировать;
  • поле, по которому хотим сортировать;
  • направление сортировки, которое может быть либо “asc”, либо “desc”.

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

По умолчанию сортировка будет производиться в направлении увеличения. Поэтому в следующей строке кода мы проверяем, если направление “desc”, то есть сортировка в обратном порядке, то мы просто перевернем полученный массив (array_reverse).

Обратите внимание, что мы не присваиваем результат работы usort никакой переменной. Дело в том, что эта функция изменяет переданный массив, а возвращает она всегда true. Именно по этому записывать результат ее работы в переменную не нужно. $arr уже и так будет изменен.

Осталось написать функцию custom_sorter, которая и будет сортировать массив.

function custom_sorter($field){
    return function($a, $b) use ($field) {
        if($a[$field] == $b[$field]){
            return 0;
        }
        return ($a[$field] < $b[$field]) ? -1 : 1;
    };
}

custom_sorter принимает в качестве параметра поле сортировки. Она возвращает анонимную функцию, которая сравнивает элементы по переданному полю и сортирует их.

Весь итоговый код примера получается вот таким:

 $data = [
    ['id' => 7, 'age' => 47],
    ['id' => 3, 'age' => 32],
    ['id' => 5, 'age' => 58],
    ['id' => 1, 'age' => 23]
];

function my_sort($arr, $field, $order){
    usort($arr, custom_sorter($field));
    if($order == 'desc'){
        return array_reverse($arr);
    }
    return $arr;
}

function custom_sorter($field){
    return function($a, $b) use ($field) {
        if($a[$field] == $b[$field]){
            return 0;
        }
        return ($a[$field] < $b[$field]) ? -1 : 1;
    };
}

Чтобы проверить работу функции мы можем вызвать ее и результат распечатать на экран. Например:

var_dump(my_sort($data, 'age', 'asc'));

/* 
array(4) {
  [0]=>
  array(2) {
    ["id"]=>
    int(1)
    ["age"]=>
    int(23)
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(3)
    ["age"]=>
    int(32)
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(7)
    ["age"]=>
    int(47)
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(5)
    ["age"]=>
    int(58)
  }
}

*/

или

var_dump(my_sort($data, 'id', 'desc'));

/*
array(4) {
  [0]=>
  array(2) {
    ["id"]=>
    int(7)
    ["age"]=>
    int(47)
  }
  [1]=>
  array(2) {
    ["id"]=>
    int(5)
    ["age"]=>
    int(58)
  }
  [2]=>
  array(2) {
    ["id"]=>
    int(3)
    ["age"]=>
    int(32)
  }
  [3]=>
  array(2) {
    ["id"]=>
    int(1)
    ["age"]=>
    int(23)
  }
}
*/

Это базовый пример, того, как можно реализовать сортировку многомерного ассоциативного массива. Можно улучшать его под свои нужды.

Надеюсь эта статья вам пригодилась.

Tags:

Leave a Reply