可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I\'m trying to sort a multidimensional array by multiple keys, and I have no idea where to start. I looked at uasort, but wasn\'t quite sure how to write a function for what I need.
I need to sort by the state, then event_type, then date.
My array looks like this:
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
回答1:
You need 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);
As of PHP 5.5.0:
array_multisort(array_column($mylist, \'event_type\'), SORT_DESC,
array_column($mylist, \'title\'), SORT_ASC,
$mylist);
$mylist
is now:
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\',
),
)
回答2:
You can do it with usort
. The $cmp_function
argument could be:
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\']);
}
For an arbitrary number of fields in PHP 5.3, you can use closures to create a comparison function:
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\')))
For an arbitrary number of fields of different types in 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\')))
回答3:
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);
回答4:
I have tried to below code and i successfully
array code
$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\')
);
call array sorting function
$songs = subval_sort($songs,\'artist\');
print_r($songs);
array sorting funcation
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;
}
if array reverse sorting function
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;
}
回答5:
Improving on @Stijn Leenknegt\'s genius code, here is my 2 cent pragmatic function:
$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\"]));
回答6:
if you want to sort multi dimentional array
first array is :
$results[\'total_quote_sales_person_wise\'][\'quote_po\'];
second one is :
$results[\'total_quote_sales_person_wise\'][\'quote_count\'];
this both multidimentional array you want to sort descending order at one time then use this code :
array_multisort($results[\'total_quote_sales_person_wise\'][\'quote_po\'],SORT_DESC, $results[\'total_quote_sales_person_wise\'][\'quote_count\'],SORT_DESC);