Сортировка многомерного массива несколькими ключами

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

Мне нужно отсортировать по состоянию, затем event_type, затем по дате.

Мой массив выглядит так:

Array ( [0] => Array ( [ID] => 1 [title] => Boring Meeting [date_start] => 2010-07-30 [time_start] => 06:45:PM [time_end] => [state] => new-york [event_type] => meeting ) [1] => Array ( [ID] => 2 [title] => Find My Stapler [date_start] => 2010-07-22 [time_start] => 10:45:AM [time_end] => [state] => new-york [event_type] => meeting ) [2] => Array ( [ID] => 3 [title] => Mario Party [date_start] => 2010-07-22 [time_start] => 02:30:PM [time_end] => 07:15:PM [state] => new-york [event_type] => party ) [3] => Array ( [ID] => 4 [title] => Duct Tape Party [date_start] => 2010-07-28 [time_start] => 01:00:PM [time_end] => [state] => california [event_type] => party ) ...... etc 

Вам понадобится array_multisort

 $mylist = array( array('ID' => 1, 'title' => 'Boring Meeting', 'event_type' => 'meeting'), array('ID' => 2, 'title' => 'Find My Stapler', 'event_type' => 'meeting'), array('ID' => 3, 'title' => 'Mario Party', 'event_type' => 'party'), array('ID' => 4, 'title' => 'Duct Tape Party', 'event_type' => 'party') ); # get a list of sort columns and their data to pass to array_multisort $sort = array(); foreach($mylist as $k=>$v) { $sort['title'][$k] = $v['title']; $sort['event_type'][$k] = $v['event_type']; } # sort by event_type desc and then title asc array_multisort($sort['event_type'], SORT_DESC, $sort['title'], SORT_ASC,$mylist); 

Начиная с PHP 5.5.0:

 array_multisort(array_column($mylist, 'event_type'), SORT_DESC, array_column($mylist, 'title'), SORT_ASC, $mylist); 

$mylist :

 array ( 0 => array ( 'ID' => 4, 'title' => 'Duct Tape Party', 'event_type' => 'party', ), 1 => array ( 'ID' => 3, 'title' => 'Mario Party', 'event_type' => 'party', ), 2 => array ( 'ID' => 1, 'title' => 'Boring Meeting', 'event_type' => 'meeting', ), 3 => array ( 'ID' => 2, 'title' => 'Find My Stapler', 'event_type' => 'meeting', ), ) 

Вы можете сделать это с помощью usort . Аргумент $cmp_function может быть:

 function my_sorter($a, $b) { $c = strcmp($a['state'], $b['state']); if($c != 0) { return $c; } $c = strcmp($a['event_type'], $b['event_type']); if($c != 0) { return $c; } return strcmp($a['date_start'], $b['date_start']); } 

Для произвольного количества полей в PHP 5.3 вы можете использовать замыкания для создания функции сравнения:

 function make_cmp($fields, $fieldcmp='strcmp') { return function ($a, $b) use (&$fields) { foreach ($fields as $field) { $diff = $fieldcmp($a[$field], $b[$field]); if($diff != 0) { return $diff; } } return 0; } } usort($arr, make_cmp(array('state', 'event_type', 'date_start'))) 

Для произвольного количества полей разных типов в PHP 5.3:

 function make_cmp($fields, $dfltcmp='strcmp') { # assign array in case $fields has no elements $fieldcmps = array(); # assign a comparison function to fields that aren't given one foreach ($fields as $field => $cmp) { if (is_int($field) && ! is_callable($cmp)) { $field = $cmp; $cmp = $dfltcmp; } $fieldcmps[$field] = $cmp; } return function ($a, $b) use (&$fieldcmps) { foreach ($fieldcmps as $field => $cmp) { $diff = call_user_func($cmp, $a[$field], $b[$field]); if($diff != 0) { return $diff; } } return 0; } } function numcmp($a, $b) { return $a - $b; } function datecmp($a, $b) { return strtotime($a) - strtotime($b); } /** * Higher priority come first; a priority of 2 comes before 1. */ function make_evt_prio_cmp($priorities, $default_priority) { return function($a, $b) use (&$priorities) { if (isset($priorities[$a])) { $prio_a = $priorities[$a]; } else { $prio_a = $default_priority; } if (isset($priorities[$b])) { $prio_b = $priorities[$b]; } else { $prio_b = $default_priority; } return $prio_b - $prio_a; }; } $event_priority_cmp = make_evt_prio_cmp( array('meeting' => 5, 'party' => 10, 'concert' => 7), 0); usort($arr, make_cmp(array('state', 'event' => $event_priority_cmp, 'date_start' => 'datecmp', 'id' => 'numcmp'))) 
 class Sort { private $actual_order = 'asc'; private $actual_field = null; public function compare_arrays($array1, $array2) { if ($array1[$this->actual_field] == $array2[$this->actual_field]) { return 0; } elseif ($array1[$this->actual_field] > $array2[$this->actual_field]) { return ($this->actual_order == 'asc' ? 1 : -1); } else { return ($this->actual_order == 'asc' ? -1 : 1); } } public function order_array(&$array) { usort($array, array($this, 'compare_arrays')); } public function __construct ($field, $actual_order = 'asc') { $this->actual_field = $field; $this->actual_order = $actual_order; } } // use $sort = new Sort ("state"); $sort->order_array($array); 

Я попытался под кодом, и я успешно

код массива

 $songs = array( '1' => array('artist'=>'Smashing Pumpkins', 'songname'=>'Soma'), '2' => array('artist'=>'The Decemberists', 'songname'=>'The Island'), '3' => array('artist'=>'Fleetwood Mac', 'songname' =>'Second-hand News') ); 

функция сортировки массива вызовов

 $songs = subval_sort($songs,'artist'); print_r($songs); 

функция сортировки массива

 function subval_sort($a,$subkey) { foreach($a as $k=>$v) { $b[$k] = strtolower($v[$subkey]); } asort($b); foreach($b as $key=>$val) { $c[] = $a[$key]; } return $c; } 

если функция обратного сортирования массива

 function subval_sort($a,$subkey) { foreach($a as $k=>$v) { $b[$k] = strtolower($v[$subkey]); } arsort($b); foreach($b as $key=>$val) { $c[] = $a[$key]; } return $c; } 

Улучшая гениальный код @Stijn Leenknegt, вот моя 2-процентная прагматическая функция:

 $data[] = array('volume' => 67, 'edition' => 2); $data[] = array('volume' => 86, 'edition' => 1); $data[] = array('volume' => 85, 'edition' => 6); $data[] = array('volume' => 98, 'edition' => 2); $data[] = array('volume' => 86, 'edition' => 6); $data[] = array('volume' => 67, 'edition' => 7); function make_cmp(array $sortValues) { return function ($a, $b) use (&$sortValues) { foreach ($sortValues as $column => $sortDir) { $diff = strcmp($a[$column], $b[$column]); if ($diff !== 0) { if ('asc' === $sortDir) { return $diff; } return $diff * -1; } } return 0; }; } usort($data, make_cmp(['volume' => "desc", 'edition' => "asc"])); 

если вы хотите сортировать многомерный массив

первый массив:

 $results['total_quote_sales_person_wise']['quote_po']; 

второй:

 $results['total_quote_sales_person_wise']['quote_count']; 

этот многомерный массив, который вы хотите отсортировать по убыванию в одно время, затем используйте этот код:

 array_multisort($results['total_quote_sales_person_wise']['quote_po'],SORT_DESC, $results['total_quote_sales_person_wise']['quote_count'],SORT_DESC);