Have you ever had to sort an array in PHP? There are a bunch of functions available, the most common being sort(). This function does a default sorting of the values in your array. So if you have numbers or want to do alphabetical sorting, sort()
will get the job done.
But what if you require a more complex sorting logic? Let's say you have an array of names that need to be sorted in a specific order. I don't know, because your client says so. Let me show you how.
Let's say your DB returns a list of names in an array:
$names = array("Christian", "Daniel", "Adrian");
And your client says they need to be arranged in the following order: Adrian, Christian, Daniel. You can use the usort() function together with a comparator function you write yourself. How does this system work?
As a second argument of the usort()
function, we pass in the name of our custom comparator function. The way this gets processed is that all the values in the array that needs sorting are passed to this function 2 at the time (usually you'll see them as $a
and $b
). This is done to determine which one takes precedence over which. The comparator has to return 0 if the 2 values are considered equal, a negative integer if the first value is less than the second value or a positive integer if the second value is less than the first. What less means is up to you to determine. So let's put this in practice with our example:
function _name_comparer($a, $b) {
$correct_order = array("Adrian", "Christian", "Daniel");
$a_key = array_search($a, $correct_order);
$b_key = array_search($b, $correct_order);
if ($a_key == $b_key) {
return 0;
}
return ($a_key < $b_key) ? -1 : 1;
}
usort($names, "_name_comparer");
So what happens in my comparator function? First, I create an array that contains the proper order of the names. This means that each value has an integer key that can be easily compared (and that I store in the $a_key
and $b_key
variables). After comparing these, I return 0, a negative or positive integer. The result is that the $names
array gets resorted in the order they appear in the $correct_order
local variable I created. And that's it.
If the $names
variable is associative and you need to maintain the keys as they were, you can use the uasort() function:
$names = array(
"christian" => "Christian",
"daniel" => "Daniel",
"adrian" => "Adrian",
);
uasort($names, "_name_comparer");
The comparator function can stay the same, but the uasort()
function will take into account and maintain the index association of your values.
And that's it. Hope this helps.
Daniel Sipos
Danny founded WEBOMELETTE in 2012 as a passion project, mostly writing about Drupal problems he faced day to day, as well as about new technologies and things that he thought other developers would find useful. Now he now manages a team of developers and designers, delivering quality products that make businesses successful.
Comments
Let the DB engine do the sorting
Nice post outlining how to use the sorts. Just a quick tip from a former uasort() abuser: Let the database engine do the sorting where possible. Especially for simple alphabetical sorts.
Sorting in PHP can be expensive but database engines like MySQL are designed and optimized to perform sorting operations. Where possible (and especially when easy), write the sorting logic into the query. For a simple alphabetical sort, the ORDER BY operator should suffice. If the sort is complex (or the PHP dev isn't well versed in SQL), it may be best to go ahead and use that uasort() now and consult a SQL specialist later if and when performance becomes a concern.
In reply to Let the DB engine do the sorting by Anonnonon (not verified)
Hey there,
Hey there,
Indeed. But for sorting like the example I mentioned I don't believe you can pass on to MySQL to handle.
Best,
D
Just What I Needed
Thanks a lot.
One small doubt
Thank you. This post is clear and I easily understood this. But i want to know how the sorting actually works. The compare function is going to return 0 or 1 or -1. Using that integers, how usort functions sort.
Lets say, in your example, what exact value is assigned to ~~~$a~~~ argument and ~~~$b~~~ argument, during the first turn. If ~~~$a="christian"~~~ and ~~~$b="daniel"~~~ , then compare function will return 1. Now, how will usort function sort those two names (i.e. which name comes first on comparing those two names).
I am currently learning PHP and thank you in advance.
Add new comment