posted by kevin on May 21, 2009
Update
Please read the comments as Evan has pointed out the function 'usort' would be the appropriate function for what I was trying to do, however feel free to read the post to read about a 'dirty hack' way of doing it. Also note that if you need to preserve your key association, use uasort instead.

At some point you'll probably need to sort a multi-dimentional array. Sorting it is very easy, however you might not have everything in the proper order to be able to sort it correctly.

Lets look at this array:

 
<?php
$array = array(
    array(
        'username' => 'kevinkorb',
        'last_name' => 'korb',
        'first_name' => 'kevin',
        'grade' => 5,
    ),
 
    array(
        'username' => 'rhoda',
        'last_name' => 'Redick',
        'first_name' => 'Ulous',
        'grade' => 6,
    ),
 
    array(
        'username' => 'apple',
        'last_name' => 'Bottom',
        'first_name' => 'Jeans',
        'grade' => 7
    ),
 
);
?>
 

Now we want to sort the array by last_name, first_name in ASCENDING order.

If there is a PHP function out there that does this, I'm not yet aware of this, so we have to hack our data a bit to get it into the format we want to.

Lets look at php's function asort()

What asort will do for a multidimentional array is it will sort by your first value, then your second value etc. So if we need to sort by last_name, first_name, we're going to have to get those values to be first and second in our arrays.

How do we do that?

We'll basically remove them from the array and add them back to the array which will put those values at the end. Now once they are at the very end, we'll simply reverse the array which makes the last value first, and the second to last value second etc.

Look at this code:

 
<?php
foreach($array AS $key => $secondary_array) {
    //extract the values into local variables that we'll move.
    $first_name = $secondary_array['first_name'];
    $last_name = $secondary_array['last_name'];
 
    //remove the first and last names from the secondary array.
    unset($secondary_array['first_name'], $secondary_array['last_name']);
 
    //Add The values to the end of the array.
    $secondary_array['first_name'] = $first_name;
    $secondary_array['last_name'] = $last_name;
 
    //Reverse the array maintaining the key => val association
    $secondary_array = array_reverse($secondary_array, true);
 
    //replace the secondary array with our modified one.
    $array[$key] = $secondary_array;
 
}
?>
 

Now here I'm outputting the array before and after the previous code.

 
Array
(
    [0] => Array
        (
            [username] => kevinkorb
            [last_name] => korb
            [first_name] => kevin
            [grade] => 5
        )
 
    [1] => Array
        (
            [username] => rhoda
            [last_name] => Redick
            [first_name] => Ulous
            [grade] => 6
        )
 
    [2] => Array
        (
            [username] => apple
            [last_name] => Bottom
            [first_name] => Jeans
            [grade] => 7
        )
 
)
 
Array
(
    [0] => Array
        (
            [last_name] => korb
            [first_name] => kevin
            [grade] => 5
            [username] => kevinkorb
        )
 
    [1] => Array
        (
            [last_name] => Redick
            [first_name] => Ulous
            [grade] => 6
            [username] => rhoda
        )
 
    [2] => Array
        (
            [last_name] => Bottom
            [first_name] => Jeans
            [grade] => 7
            [username] => apple
        )
 
)
 

You notice that the info is still there, however our last_name and first_name are the top two key/value combinations there. All that's left is to sort the array.

 
asort($array);
 

And after outputting the array we now have:

 
Array
(
    [2] => Array
        (
            [last_name] => Bottom
            [first_name] => Jeans
            [grade] => 7
            [username] => apple
        )
 
    [1] => Array
        (
            [last_name] => Redick
            [first_name] => Ulous
            [grade] => 6
            [username] => rhoda
        )
 
    [0] => Array
        (
            [last_name] => korb
            [first_name] => kevin
            [grade] => 5
            [username] => kevinkorb
        )
 
)
 
 

Now the data that I used won't show that it's also then sorting by first_name if the last names are the same, but it is, test it out for yourself if you don't believe me.

3 comments to "Rearranging And Sorting Multi-dimentional Arrays In PHP"

#4
evan says:
May 22, 2009 at 07:15 pm
try this
 
<?
// same $array from above
function comparisonFunction($a, $b) {
	if ($a == $b) {
		return 0;
	}
	return (strtolower($a['last_name'] . $a['fist_name']) < strtolower($b['last_name'] . $b['first_name'])) ? -1 : 1;
}
 
print_r($array);
usort($array, comparisonFunction);
print_r($array);
?>
 
#5
May 23, 2009 at 12:19 am
Thanks Evan, I had never used the usort function before, I love learning new things. You can also simplify your comparisonFunction to simply contain:
 
return strcasecmp($a['last_name'].$a['first_name'], $b['last_name'].$b['first_name']);
 
:) I just realized how crappy my comment box is. Let me fix this and add php highlighting to comments.
#108
Lior says:
February 27, 2010 at 12:46 pm
Why strcasecmp (case insensitive) and not just strcmp?
Bookmark and Share

Leave a Comment

Your email address will not be published.

(You can enclose code in <php></php> blocks.)

You may use Markdown syntax.

Please enter the letters as they are shown in the image above.
Letters are not case-sensitive.