Archive for the ‘Web Design’ Category

Function to Sort an Associative Array in PHP

Wednesday, April 17th, 2013

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.