Multisorting columns in a 3D array with PHP
Today (Tuesday 4th Auguest '09) was put in a situation where I had to reorder one of the columns from my 3D array and initially started to use array_multisort as described on php.net.
Getting annoyed that it was not giving me what I needed, I started to read through the comments others had left, and tried cagret at gmail dot com example which worked a treat for me.
Basically, from my array output below, I wanted to reorder the array by 'ymd_date':
Array
(
[0] => Array
(
[title] => SimpleXMLElement Object
(
[0] => novolume: Is it just me or are there too few acronyms used in web design? More of them please!
)
[twitter_date] => SimpleXMLElement Object
(
[0] => Mon, 03 Aug 2009 15:22:01 +0000
)
[ymd_date] => 2009-08-03 16:22:01
)
[1] => Array
(
[title] => SimpleXMLElement Object
(
[0] => adamgraham: Very much enjoyed this month's Facebook Garage. Especially the talk from VCCP on the 'compare the merecat' campaign.
)
[twitter_date] => SimpleXMLElement Object
(
[0] => Wed, 22 Jul 2009 21:48:03 +0000
)
[ymd_date] => 2009-07-22 22:48:03
)
[2] => Array
(
[title] => SimpleXMLElement Object
(
[0] => rajgorsia: any one played with php symfony?
)
[twitter_date] => SimpleXMLElement Object
(
[0] => Fri, 31 Jul 2009 15:51:11 +0000
)
[ymd_date] => 2009-07-31 16:51:11
)
)
Using the above output assigned to a variable called $temp_array, the below code was magic.
$temp_array = array_multi_sort($temp_array, array('ymd_date'=>SORT_DESC));
//$temp_array = array_multi_sort($temp_array, array('ymd_date'=>SORT_DESC, 'title'=>SORT_ASC)); // if you want to add in another column to order
function array_multi_sort($array, $cols)
{
$colarr = array();
foreach($cols as $col => $order)
{
$colarr[$col] = array();
foreach ($array as $k => $row)
{
$colarr[$col]['_'.$k] = strtolower($row[$col]);
}
}
$eval = 'array_multisort(';
foreach($cols as $col => $order)
{
$eval .= '$colarr[''.$col.''],'.$order.',';
}
$eval = substr($eval,0,-1).');';
eval($eval);
$ret = array();
foreach($colarr as $col => $arr)
{
foreach($arr as $k => $v)
{
$k = substr($k,1);
if (!isset($ret[$k])) $ret[$k] = $array[$k];
$ret[$k][$col] = $array[$k][$col];
}
}
return $ret;
}