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

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

Array ( [0] => Array ( [name] => 'Sony TV' [price] => 600.00 ) [1] => Array ( [name] => 'LG TV' [price] => 350.00 ) [2] => Array ( [name] => 'Samsung TV' [price] => 425.00 ) } 

То, что я хочу сделать, это отсортировать строки (элементы внешнего массива) по цене. Ниже приведен пример того, чего я хочу достичь:

 Array ( [0] => Array ( [name] => 'LG TV' [price] => 350.00 ) [1] => Array ( [name] => 'Samsung TV' [price] => 425.00 ) [2] => Array ( [name] => 'Sony TV' [price] => 600.00 ) } 

Как вы можете видеть, мне не нужно сохранять ключи внешнего массива.

Вам нужно использовать usort – функцию, которая сортирует массивы через определенную пользователем функцию. Что-то вроде:

 function cmp($a, $b) { if ($a["price"] == $b["price"]) { return 0; } return ($a["price"] < $b["price"]) ? -1 : 1; } usort($yourArray,"cmp") 

Вы можете использовать usort() :

 function sort($a, $b) { if ($a['price'] == $b['price']) return 0; return ($a['price'] > $b['price']) ? 1 : -1; } usort($array, 'sort'); 

Еще лучше, если вы создадите такой класс, чтобы повторно использовать код:

 class FieldSorter { public $field; function __construct($field) { $this->field = $field; } function cmp($a, $b) { if ($a[$this->field] == $b[$this->field]) return 0; return ($a[$this->field] > $b[$this->field]) ? 1 : -1; } } $sorter = new FieldSorter('price'); usort($array, array($sorter, "cmp")); 

Таким образом, вы можете легко отсортировать по другим полям.

И хотя вы сказали, что ключи внешнего массива не нужно сохранять, вы можете легко достичь этого, используя uasort() вместо usort .

Вы можете использовать функцию usort с обратным вызовом

http://www.php.net/manual/en/function.usort.php

Этот вопрос немного стар, но оставит здесь ответ на будущее.

Из функции php.net-Multisort мы можем использовать приведенный ниже код;

  $data= [['volume' => 67, 'edition' => 2],['volume' => 85, 'edition' => 6],...]; foreach ($data as $key => $row) { $volume[$key] = $row['volume']; $edition[$key] = $row['edition']; } array_multisort($volume, SORT_DESC, $edition, SORT_ASC, $data); 

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

Для более динамичного и надежного примера рассмотрим ниже;

Предположим, у меня есть данные ниже;

 $data = [[1, 'Amanda', 'Wright', 'awright0@usnews.com', 'Female', '135.114.57.89', 31237], [2, 'Theresa', 'Larson', 'tlarson1@51.la', 'Female', '207.108.96.210', 91011], [3, 'Walter', 'Kennedy', 'wkennedy2@baidu.com', 'Male', '199.147.223.56', 50114], [4, 'Andrea', 'Richards', 'arichards3@google.nl', 'Female', '230.195.124.95', 76489], [5, 'Carol', 'Jones', 'cjones4@elegantthemes.com', 'Female', '250.197.111.90', 56501], [6, 'Alice', 'Freeman', 'afreeman5@elegantthemes.com', 'Female', '52.195.252.131', 77170], [7, 'Gerald', 'Fisher', 'gfisher6@slashdot.org', 'Male', '81.2.22.62', 75625],....] 

Если нам нужно отсортировать данные массива выше, мы можем установить порядок сортировки в массиве с использованием синтаксиса;

  $qTable[$index]=$sort_order; Eg $qTable=[1=>'asc',4=>'desc',3=>'asc']; 

Это означает столбец сортировки 1 ASC, столбец 4 DESC, а затем столбец 3 ASC. Затем мы можем использовать приведенную ниже функцию для сортировки данных мультимодальной базы данных;

  function sortMulti($data, $orders) { $args = []; foreach ($data as $key => $row) { foreach ($orders as $index => $order) { if (!isset($row[$index])) continue; //Ignore if column does'nt exist $args[$index]['d'][$key] = $row[$index]; //Get all values within the column $args[$index]['o'] = 'desc' == strtolower($order) ? SORT_DESC : SORT_ASC; //Get the Sort order 'ASC' is the default } } $p = []; //Below we need to organize our entries as arguments for array_multisort foreach ($args as $arg) { $p[] = $arg['d']; $p[] = $arg['o']; //Below we need to check if column contains only numeric or not. //If all values are numeric, then we use numeric sort flag, otherwise NATURAL //Manipulate for more conditions supported $p[] = count($arg['d']) == count(array_filter($arg['d'], 'is_numeric')) ? SORT_NUMERIC : SORT_NATURAL; } $p[] = &$data; //Pass by reference call_user_func_array('array_multisort', $p); //Call Php's own multisort with parameters in required order. return $data; //Our final array sorted. } 

Тогда мы можем использовать его, как показано ниже;

 $data=[[...],[...],...]; $order=[1=>'asc',4=>'desc',3=>'asc']; $sorted=sortMulti($data,$order); по $data=[[...],[...],...]; $order=[1=>'asc',4=>'desc',3=>'asc']; $sorted=sortMulti($data,$order); по $data=[[...],[...],...]; $order=[1=>'asc',4=>'desc',3=>'asc']; $sorted=sortMulti($data,$order); по $data=[[...],[...],...]; $order=[1=>'asc',4=>'desc',3=>'asc']; $sorted=sortMulti($data,$order); 

Для данных массива ключевых значений. Eg $data=[['c1'=>1212,'c2'=>'mynames'],...]; Используйте порядок как $order=['c1'=>'desc','c10'=>'asc'];

Я протестировал выше с массивом из 1000 записей. Надеюсь, это поможет кому-то.

Альтернативой usort является создание массива, который индексирует массив, который вы хотите отсортировать, и индексируется данными, которые вы хотите отсортировать.

В нижеприведенном фрагменте $ customAttributes представляет собой массив объектов, которые я хотел бы сортировать по имени . Создается первый сортировка $ , индексируется по имени и содержит индекс массива соответствующего элемента $ customAttributes .

 $sort = []; foreach( $customAttributes as $c => $ca ) { $sort[$ca->name] = $c; } 

Затем ksort используется для сортировки массива по ключу.

 ksort( $sort ); 

После сортировки массива $ sort , итерации через него и создания $ упорядоченного массива.

 $ordered = []; foreach( $sort as $s ) { $ordered[] = $customAttributes[$s]; } 

Мне нравится это решение, потому что вызовов функций меньше, чем при использовании обратных вызовов.

Вы можете создать функцию самостоятельно, как показано ниже

private function orderArrayBycolumn ($ array, $ column) {

  $newArray = []; foreach ($array as $key => $value) { $newArray[$value[$column]] = $value; } $array = []; ksort($newArray); foreach ($newArray as $key => $value) { $array[] = $value; } return $array; }