I needed to sort an associative array into the correct order for display, PHP has various functions for sorting arrays but I couldn’t find a simple generic one that did what I wanted. Specifically I needed to sort on several keys and wanted a reasonably tidy solution (so much easier to figure out what is going on when you come back it months/years later).
The Sort
Because I was using CodeIgniter for this site I put the following function in helpers/MY_array_helper.php so I can use it from other parts of the site. But it would work just as well if defined locally.
function assoc_array_sort($a, $b, $key, $sequence = 'ASC')
{
/*
* Simple function for sorting between 2 values
* Designed to be called within the function called by usort or uasort
*
* $key is the key for the associative array so if we want to compare values of $array['my_key']
* $key would be set to 'my_key'
*
* Default sequence is ASC but can reverse sort by passing DESC instead
*/
if (strtoupper($sequence) == 'DESC') {
$lower = 1;
$higher = -1;
} else {
$lower = -1;
$higher = 1;
}
if ($a[$key] == $b[$key]) {
return 0;
} else if ($a[$key] < $b[$key]) {
return $lower;
} else {
return $higher;
}
}
Calling the Sort
The array I needed to sort is called $memberships so the call is;
uasort($memberships, 'membership_sort');
membership_sort is an intermediate function sitting between uasort (or usort) and assoc_array_sort. If like me you are using CodeIgniter you will need to load the array_helper before calling this function.
$this->load->helper('array'); // load array_helper so we can use the sort in MY_array_helper
function membership_sort($x, $y)
{
/*
* Use assoc_array_sort to determine sequence
* but where values match call again for the next variable to be checked.
* This should give us an array in order
* - committee_sequence
* - committee_name
* - role_sequence
* - role-name
*/
$ret_var = assoc_array_sort($x, $y, 'committee_sequence','ASC');
if ($ret_var == 0) {
$ret_var = assoc_array_sort($x, $y, 'committee_name','ASC');
if ($ret_var == 0) {
$ret_var = assoc_array_sort($x, $y, 'role_sequence','ASC');
if ($ret_var == 0) {
$ret_var = assoc_array_sort($x, $y, 'committee_name','ASC');
}
}
}
return $ret_var;
}
You can see that the first time assoc_array_sort is called it is sorting on $memberships[‘committee_sequence’], if the values don’t match it returns -1 or 1 depending on whether the first or second value is higher. But it the values are equal it drops through to the next sort key $memberships[‘committee_name’] and repeats the process.
I am sure there are cleverer ways to do this, I would welcome feedback telling me of better ways, but hopefully this will be useful to somebody.