Сортировка многомерного массива по нескольким ключам
Я пытаюсь отсортировать многомерный массив по несколько ключей, и я понятия не имею с чего начать. Я посмотрел на uasort, но не совсем уверен, как написать функцию, что мне нужно.
Мне нужно отсортировать по состоянию, затем event_type, затем date.
мой массив выглядит так:
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
6 ответов:
вам нужно
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 cent:
$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);