PHP Tip: Sorting Multidimensional Associative Arrays

We've all faced this problem before.  You have a multidimensional associative array, and you need to sort it by some element right in the middle.  Or even sort by several elements.  How do you do it?  Well, here's a quick tip that will keep you from having to program custom comparison routines to get usort() to work.

For example, let's say your array looks something like this:

// array structure:  $a[person name][age][pet name] = pet age

$a["mary"][35]["spot"] = 5;
$a["bob"][29]["nosy"] = 8;
$a["mary"][35]["fido"] = 12;
$a["bob"][29]["eve"] = 2;

Now let's say you want to know the order of pet names, sorted by owner's age, then pet age, then person name, then pet name.  If we go the traditional usort route, we would have to program several annoying and confusing comparison functions.  So, here's the trick:  flatten out the array!

Think about it:  if you flatten the array, so that every element is just one string, you can use PHP's regular sort() command.  So, step one, flatten that array:

// flatten out the array to be a new array of strings,
// delimited by a ~ character.

// Simply foreach through all the levels...
foreach($a as $name => $value) {
  foreach($a[$name] as $age => $value) {
    foreach($a[$name][$age] as $pet_name => $pet_age) {
      // Construct a new string!  Since we want to
      // order it by age, pet age, person name, pet name, let's concat
      // in that order!
      $new[] = "$age~$pet_age~$name~$pet_name";
    }
  }
}

So, coming out of this function, we have a new array, named $new, which looks a little like this:

/* vardump of $new:
    [0] => 35~5~mary~spot
    [1] => 35~12~mary~fido
    [2] => 29~8~bob~nosy
    [3] => 29~2~bob~eve
*/

Now, let's run a simple sort() on this array.  Here's the result...

sort($new);

/* $new now looks like:
    [0] => 29~2~bob~eve
    [1] => 29~8~bob~nosy
    [2] => 35~12~mary~fido
    [3] => 35~5~mary~spot
*/

The hard part's over.  As you can see, our $new array has our pet names in the correct sorting order.  First by age, then pet age, then person name.  Now all we need to do is pull out just our pet names:

// Create our final array of $pets, now in the correct
// order.
foreach ($new as $line) {
  $t = explode("~", $line);
  // $t looks like this:  [0] = age, [1] = pet age, [2] = name
  //                      [3] = pet name
  // So, we now have access to the pet names, sorted in the
  // in the order we wanted.
  $pets[] = $t[3];
}

And that's it!  Here's what $pets looks like:

/* $pets looks like:
    [0] => eve
    [1] => nosy
    [2] => fido
    [3] => spot
*/

So as you can see, it is relatively easy to sort an associative array by any criteria.  I hope this helps!

 


Software License Fine Print

Creative Commons LicenseThis code is licensed as-is, with no warranty or guarantee, under a Creative Commons Attribution 3.0 Unported License.

You may use this code however you want, even in commercial products, but only if you include attribution to me, Richard Peacock, as the original author of this small portion of code, but not in a way that implies I endorse your project.

For example, on a Help/Credits screen:  Portions of this project were based on work freely obtained from these developers: Richard Peacock (http://richardpeacock.com), NAME HERE, etc.  These outside developers neither endorse nor support this software.

If you use this code, feel free to email me to let me know!  I'll include a link to your project here.

Hi Richard , Its very helpful

Hi Richard ,

Its very helpful thank you very much...

Hope for such more useful articles from you.... :)

I'm glad you found it

I'm glad you found it useful!

Richard