Reputation: 7101
Given the following array:
$array = array(
'note' => array('test', 'test1', 'test2', 'test3', 'test4'),
'year' => array('2011','2010', '2012', '2009', '2010'),
'type' => array('journal', 'conference', 'editorial', 'conference','conference'),
);
Array can be easily transposed if it is easier (using the following function):
for ($i = 0; $i < count($array['type']); $i++)
foreach ($array as $key => $value)
$temp[$i][$key] = $value[$i];
print_r($temp);
And I want to sort it using the following criteria:
$sortby = ('journal', 'editorial', 'conference')
year DESC
for every category.Desired result:
Array
(
[note] => Array
(
[0] => test
[1] => test2
[2] => test1
[3] => test4
[4] => test3
)
[year] => Array
(
[0] => 2011
[1] => 2012
[2] => 2010
[3] => 2010
[4] => 2009
)
[type] => Array
(
[0] => journal
[1] => editorial
[2] => conference
[3] => conference
[4] => conference
)
)
Upvotes: 0
Views: 519
Reputation: 46602
If you transpose your input array, then you'll be able to sort by column at a time.
$Array = array(
array('note' => 'test1', 'year' => '2011', 'type' => 'journal'),
array('note' => 'test2', 'year' => '2012', 'type' => 'editorial'),
array('note' => 'test3', 'year' => '2012', 'type' => 'conference'),
array('note' => 'test4', 'year' => '2012', 'type' => 'conference'),
array('note' => 'test5', 'year' => '2012', 'type' => 'conference')
);
Let's sort them by year
value.
function array_sort_by_column(&$arr, $col, $dir = SORT_DESC) {
$sort_col = array();
foreach ($arr as $key=> $row) {
$sort_col[$key] = $row[$col];
}
return array_multisort($sort_col, $dir, $arr);
}
array_sort_by_column($Array, 'year');
print_r($Array);
Output:
Array
(
[0] => Array
(
[note] => test2
[year] => 2012
[type] => editorial
)
[1] => Array
(
[note] => test3
[year] => 2012
[type] => conference
)
[2] => Array
(
[note] => test4
[year] => 2012
[type] => conference
)
[3] => Array
(
[note] => test5
[year] => 2012
[type] => conference
)
[4] => Array
(
[note] => test1
[year] => 2011
[type] => journal
)
)
Sort them by note
value.
array_sort_by_column($Array, 'note');
print_r($Array);
Output:
Array
(
[0] => Array
(
[note] => test5
[year] => 2012
[type] => conference
)
[1] => Array
(
[note] => test4
[year] => 2012
[type] => conference
)
[2] => Array
(
[note] => test3
[year] => 2012
[type] => conference
)
[3] => Array
(
[note] => test2
[year] => 2012
[type] => editorial
)
[4] => Array
(
[note] => test1
[year] => 2011
[type] => journal
)
)
Sort by type
value.
array_sort_by_column($Array, 'type');
print_r($Array);
Output:
Array
(
[0] => Array
(
[note] => test1
[year] => 2011
[type] => journal
)
[1] => Array
(
[note] => test2
[year] => 2012
[type] => editorial
)
[2] => Array
(
[note] => test3
[year] => 2012
[type] => conference
)
[3] => Array
(
[note] => test4
[year] => 2012
[type] => conference
)
[4] => Array
(
[note] => test5
[year] => 2012
[type] => conference
)
)
Upvotes: 2
Reputation: 47894
Use a single array_multisort()
call. Write your rules as leading parameters, then write an subarrays that have not been passed in in their original (reference-able) form. The below executes the sorting process as:
The last two patameters are "coming along for the ride" -- they are mentioned so that they are mutated in accordance with earlier parameter sorting. Demo
$array = [
'note' => ['test', 'test1', 'test2', 'test3', 'test4'],
'year' => ['2011', '2010', '2012', '2009', '2010'],
'type' => ['journal', 'conference', 'editorial', 'conference', 'conference'],
];
$priorities = array_flip(['journal', 'editorial', 'conference']);
array_multisort(
array_map(fn($t) => $priorities[$t] ?? PHP_INT_MAX, $array['type']),
$array['year'],
SORT_DESC,
$array['note'],
$array['type']
);
var_export($array);
Upvotes: 0