PHP Basics: Sorting Arrays

Arrays are wonderful things. I can’t imagine using a programming language that does not have support for arrays. For newbies, arrays might be something that’s difficult to understand at first, but once you get used to it, it’s almost impossible to live without. Guaranteed!

If you are not familiar with what arrays are, visit the PHP manual. Alternatively, there’s a introduction to arrays at developer.com.

In this post, I’m not going to cover the same ground but instead touch on sorting of arrays.


PHP provides a number of function which you can use to sort arrays.

Sorting by its values
Sorting an array by its values is probably the most common way of performing a sort, and the most straighfoward. PHP provides the sort() function for doing this.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$nums = array(14, 3.2, -5, 1.3, 0);
sort($nums);
print_r($nums);
 
/* Outputs:
Array 
(
    [0] => -5
    [1] => 0
    [2] => 1.3
    [3] => 3.2
    [4] => 14
)
*/

Example 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$movies = array('A Fish Called Wanda', 'The Godfather', 'Finding Nemo', 'Star Wars', 'Grease');
sort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [0] => A Fish Called Wanda
    [1] => Finding Nemo
    [2] => Grease
    [3] => Star Wars
    [4] => The Godfather
)
*/

Example 3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$movies = array('Comedy'=>'A Fish Called Wanda', 'Drama'=>'The Godfather', 
		'Animation'=>'Finding Nemo', 'Sci-Fi'=>'Star Wars', 'Musical'=>'Grease');
sort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [0] => A Fish Called Wanda
    [1] => Finding Nemo
    [2] => Grease
    [3] => Star Wars
    [4] => The Godfather
)
*/

So, it all looks pretty straightfoward right? The arrays are sorted in ascending order. But what has happened to the keys for the last example for $movies? sort() will reset all the indexes, so you have lost your original keys. To get around this you can use the asort() function instead, which works the same as sort except that it preserves the original key/value mapping.

Example 4:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$movies = array('Comedy'=>'A Fish Called Wanda', 'Drama'=>'The Godfather', 
		'Animation'=>'Finding Nemo', 'Sci-Fi'=>'Star Wars', 'Musical'=>'Grease');
asort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [Comedy] => A Fish Called Wanda
    [Animation] => Finding Nemo
    [Musical] => Grease
    [Sci-Fi] => Star Wars
    [Drama] => The Godfather
)
*/

So how about sorting in descending order? Well, the functions to in this case are rsort() and arsort()

Example 5:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$movies = array('Comedy'=>'A Fish Called Wanda', 'Drama'=>'The Godfather', 
		'Animation'=>'Finding Nemo', 'Sci-Fi'=>'Star Wars', 'Musical'=>'Grease');
arsort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [Drama] => The Godfather
    [Sci-Fi] => Star Wars
    [Musical] => Grease
    [Animation] => Finding Nemo
    [Comedy] => A Fish Called Wanda
)
*/

Sorting by its keys
For associative arrays, it is just as important to be able to sort the array by its keys. The ksort() and krsort() functions does exactly that.

Example 6:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$movies = array('Comedy'=>'A Fish Called Wanda', 'Drama'=>'The Godfather', 
		'Animation'=>'Finding Nemo', 'Sci-Fi'=>'Star Wars', 'Musical'=>'Grease');
ksort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [Animation] => Finding Nemo
    [Comedy] => A Fish Called Wanda
    [Drama] => The Godfather
    [Musical] => Grease
    [Sci-Fi] => Star Wars
)
*/

Example 7:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$movies = array('Comedy'=>'A Fish Called Wanda', 'Drama'=>'The Godfather', 
		'Animation'=>'Finding Nemo', 'Sci-Fi'=>'Star Wars', 'Musical'=>'Grease');
krsort($movies);
print_r($movies);
 
/* Outputs:
Array
(
    [Sci-Fi] => Star Wars
    [Musical] => Grease
    [Drama] => The Godfather
    [Comedy] => A Fish Called Wanda
    [Animation] => Finding Nemo
)
*/

Sorting using custom comparison functions
It is also possible to create your own sort criteria and apply it to an array. Three functions are provided for you to do just that – usort(), uasort() and uksort(). The following example, I’m going to sort my fruits array by arranging the quantity with odd numbers first followed by even numbers, in descending order. I’m going to use uasort() because more often than not, you want to preserve your keys, which usort() will not do.

Example 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function oddfirst($i, $j)
{
	$value = 0; # default return value (do nothing)
	if($i % 2) $value--;
	if($j % 2) $value++;	
	if($value == 0) $value = $j < $i;
	return $value;
}
$fruits = array( 'apples' => 37, 'mangoes' => 72, 'oranges' => 92, 'bananas' => 15, 'grapes' => 52, 'kiwis' => 43);
uasort($fruits, 'oddfirst');
print_r($fruits);
 
/* Outputs:
Array
(
    [bananas] => 15
    [apples] => 37
    [kiwis] => 43
    [grapes] => 52
    [mangoes] => 72
    [oranges] => 92
)
*/

So how does this actually works? The uasort() function takes in 2 arguments – the first argument defines the array to be sorted, the second argument states the name of the function to call. In my example, that would be ‘oddfirst’.

This comparison function needs to take in 2 parameters (in my case $i and $j) and return one of three possible values – a negative number, a positive number and zero. In most cases, returning -1, 0, 1, would be sufficient. This number tells uasort() how $i compares with $j as follows.

For the oddfirst() function, my algorithm goes like this:

Sorting multi-dimensional arrays
So far, we’ve only dealt with single dimensional arrays. What about multi-dimensional arrays? PHP provides only one function to this multiple array sorting – array_multisort(). The function takes in a number of arrays as arguments, each followed optionally by one or more sort flags. Let’s take a look at the following example of movies with genre and global box office revenue, and attempt to sort the movies by revenue.

Example 9:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
$moviedata = array(
	array('movie'=>'Home Alone', 'genre'=>'Comedy', 'revenue'=>285),
	array('movie'=>'The Godfather', 'genre'=>'Drama', 'revenue'=>268),
	array('movie'=>'Finding Nemo', 'genre'=>'Animation', 'revenue'=>866),
	array('movie'=>'Star Wars', 'genre'=>'Sci-Fi', 'revenue'=>797),
	array('movie'=>'Grease', 'genre'=>'Musical', 'revenue'=>387),
	array('movie'=>'Ghostbusters', 'genre'=>'Comedy', 'revenue'=>238),
	array('movie'=>'Titanic', 'genre'=>'Drama', 'revenue'=>600)
);
 
$cols = array();
foreach($moviedata as $row) {
	foreach($row as $key => $value) {
		if( !isset($cols[$key]) )
		$cols[$key] = array();
		$cols[$key][] = $value;
	}
}
$data = $cols;
array_multisort($data['revenue'], $data['movie'], $data['genre']);
print_r($data);
 
/* Outputs:
Array
(
    [movie] => Array
        (
            [0] => Ghostbusters
            [1] => The Godfather
            [2] => Home Alone
            [3] => Grease
            [4] => Titanic
            [5] => Star Wars
            [6] => Finding Nemo
        )
 
    [genre] => Array
        (
            [0] => Comedy
            [1] => Drama
            [2] => Comedy
            [3] => Musical
            [4] => Drama
            [5] => Sci-Fi
            [6] => Animation
        )
 
    [revenue] => Array
        (
            [0] => 238
            [1] => 268
            [2] => 285
            [3] => 387
            [4] => 600
            [5] => 797
            [6] => 866
        )
 
)
*/

To be effective, array_multisort() requires that multidimensional arrays be arranged in a columnar fashion, which is done by the foreach block at line 12 in the example. After that, just call array_multisort() to sort the movie data, I define which columns I want to sort first followed by the next and so on.

You may notice that revenue is sorted in ascending order. If you want sort by descending order, just call array_multisort() with sort flags like so:

1
array_multisort($data['revenue'], SORT_DESC, $data['movie'], $data['genre']);

Well, that’s it. I hope this post helps you get started with how to sort arrays. Remember to check out PHP’s page on sorting arrays. Feel free to comment and contribute your tips on sorting arrays.

QGYMRRM2NK7K

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • Propeller
  • Reddit
  • StumbleUpon
  • Technorati
  • Yahoo! Buzz
Posted on March 14, 2010 at 10:56 pm by Eldee · Permalink
In: PHP Tutorials · Tagged with: ,

8 Responses

Subscribe to comments via RSS

  1. Written by Hermitbiker on March 15, 2010 at 11:49 am
    Permalink

    …. I better go back to the beginning for I am very much a beginner…. although I do find your tutorial very intriguing…. thank you for taking time to explain things out for all of us wishing to learn !!

  2. Written by JL on March 16, 2010 at 8:59 am
    Permalink

    Gee! Very good — write a book!

  3. Written by Sava on March 26, 2010 at 4:43 pm
    Permalink

    It’s actually pretty nice. I usually work with arrays that have values from a database … and I sort them from within the mysql_query.

  4. Written by You are now listed on FAQPAL on April 12, 2010 at 6:35 am
    Permalink

    PHP Basics: Sorting Arrays…

    PHP provides a number of function which you can use to sort arrays. Check out some examples on how to do array sorting with this post….

  5. Written by syabac on July 11, 2010 at 5:25 pm
    Permalink

    very clear explanation..
    great job..

  6. Written by arjun on September 6, 2011 at 1:44 pm
    Permalink

    Really very clear explanation . use full tutorial , great job

  7. Written by Greg on March 23, 2012 at 8:14 pm
    Permalink

    Hi, so example #9 – it keeps the correct data together? (despite 3 nested arrays separating the coloumns?)

  8. Written by base64 on September 8, 2013 at 12:33 am
    Permalink

    this is a must know for every php programmer. great explanation

Subscribe to comments via RSS

Leave a Reply