ComplexSort
ComplexSort allows you to chain together multiple comparison functions for us in PHP's usort
function. For example, if you have a an array of associative arrays, each with the fields firstName
, nickname
, age
, and favoriteColor
, and you've created comparison functions to sort by each of these fields individually, you can use ComplexSort to build a new comparison function that combines these in whichever order you like., (*1)
Examples
Say way have this array:, (*2)
// Here's some data.
$data = array(
array(
'firstName' => 'George',
'nickname' => 'Geroge Sr.',
'age' => 62,
'favoriteColor' => 'orange'
),
array(
'firstName' => 'George',
'nickname' => 'GOB',
'age' => 42,
'favoriteColor' => 'blue'
),
array(
'firstName' => 'George',
'nickname' => 'George Michael',
'age' => 16,
'favoriteColor' => 'blue'
),
array(
'firstName' => 'Buster',
'nickname' => 'Buster',
'age' => 32,
'favoriteColor' => 'violet'
)
);
And suppose we have these functions for sorting individually:, (*3)
// Some comparison functions. These aren't particular *good* ones, as they do
// nothing as far as checking if the array keys exist, but they'll work for
// this demo.
function compareFirstName($a, $b) {
if ($a['firstName'] == $b['firstName']) {
return 0;
}
return $a['firstName'] > $b['firstName'] ? 1 : -1;
}
function compareAge($a, $b) {
if ($a['age'] == $b['age']) {
return 0;
}
return $a['age'] > $b['age'] ? 1 : -1;
}
function compareColor($a, $b) {
if ($a['favoriteColor'] == $b['favoriteColor']) {
return 0;
}
return $a['favoriteColor'] > $b['favoriteColor'] ? 1 : -1;
}
We can make new comparison functions that order these individual functions in whichever order we need., (*4)
// Arrange some sort functions in a partiular order in an array.
// Pass that array to ComplexSort::makeComplexSortFunction() to combine them.
// Use this complex function with usort() to sort the data.
$sortArrays = array('compareFirstName', 'compareAge', 'compareColor');
$complexFn = ComplexSort::makeComplexSortFunction($sortArrays);
usort($data, $complexFn);
print "By firstName, age, favoriteColor: \n";
foreach ($data as $bluth) {
print $bluth['nickname'] . "\n";
}
// By firstName, age, favoriteColor:
// Buster
// George Michael
// GOB
// Geroge Sr.
$sortArrays = array('compareColor', 'compareAge');
$complexFn = ComplexSort::makeComplexSortFunction($sortArrays);
usort($data, $complexFn);
print "By favoriteColor, age: \n";
foreach ($data as $bluth) {
print $bluth['nickname'] . "\n";
}
// By favoriteColor, age:
// George Michael
// GOB
// Geroge Sr.
// Buster
Closures
The array passed to ComplexSort::makeComplexSortFunction()
can include anything that is a callable
in PHP. This means you can pass a string that names a function, or you can pass closures, like this:, (*5)
$sort = ComplexSort::makeComplexSortFunction(array(
function ($a, $b) {
if ($a->orderTotal == $b->orderTotal) {
return 0;
}
return $a->orderTotal > $b->orderTotal ? 1 : -1;
},
function ($a, $b) {
if ($a->otherField == $b->otherField) {
return 0;
}
return $a->otherField > $b->otherField ? 1 : -1;
}
));
usort($data, $sort);
Install
Composer
Add an entry for "pjdietz/complex-sort" to your composer.json file's require property. If you are not already using Composer, create a file in your project called composer.json with the following content:, (*6)
{
"require": {
"pjdietz/complex-sort": "1.*"
}
}
Use Composer to download and install ComplexSort. Run these commands from the directory containing the composer.json file., (*7)
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar install
You can now use ComplexSort by including the autoload.php file generated by Composer. vendor/autoload.php
, (*8)
Copy-and-paste
For a copy-and-paste version of the same functionality, see my original gist., (*9)
Happy sorting!, (*10)