note 111462 modified in function.usort by danbrown
| From: | danbrown@php.net | Date: | Mon, 04 Mar 2013 17:57:17 +0000 |
| Subject: | note 111462 modified in function.usort by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-193858@lists.php.net to get a copy of this message | ||
Needed to sort an array of objects based on multiple properties. (ie: Group, then Last Name, then
First Name) Doing this in multiple usorts fails because the second usort ends up shuffling the
results of the previous usort because order is undefined when criteria are equal. Ended up writing a
function that builds a comparison operator by nesting ternary operators for each field, then using
that function in usort(). Hopefully it's of use to someone else.
<?php
/*
* Sorts an array of objects by a list of properties.
* Each property can have the following options:
* 'property' can be either a public variable or a method().
* 'order' can be ASC or DESC
* 'comparer' can be string, number, or date
*
* Example:
* sortObjectsByProperties($objects, array(
* array('property'=>'getPrice()', order=>'ASC',
'comparer'=>'number'),
* array('property'=>'getName()', order=>'DESC',
'comparer'=>'string'),
* array('property'=>'created_date', order=>'ASC',
'comparer'=>'date'),
* array('property'=>'id', order=>'ASC',
'comparer'=>'number'),
* ));
*
* @author Tyler Chamberlain
*/
function sortObjectsByProperties(&$objects, $fields) {
$comparerFunctionString = "";
foreach ($fields as $field) {
if ($field['comparer'] == 'number') {
$comparerFunction = "(\$a->{$field['property']} ==
\$b->{$field['property']} ? 0 : (\$a->{$field['property']} >
\$b->{$field['property']} ? 1 : -1))";
} elseif ($field['comparer'] == 'date') {
$comparerFunction = "(strtotime(\$a->{$field['property']}) >
strtotime(\$b->{$field['property']}) ? 1 : -1)";
} else {
$comparerFunction =
"strcasecmp(\$a->{$field['property']},\$b->{$field['property']})";
}
if ($field['order'] === 'DESC') { $comparerFunction =
"-".$comparerFunction; }
$comparerFunctionString .= "$comparerFunction != 0 ? $comparerFunction : (";
}
$comparer = "return ($comparerFunctionString 0 )".str_repeat(")",
sizeof($fields)).";";
usort($objects, create_function('$a,$b', $comparer));
}
?>
--was--
Needed to sort an array of objects based on multiple properties. (ie: Group, then Last Name, then
First Name) Doing this in multiple usorts fails because the second usort ends up shuffling the
results of the previous usort because order is undefined when criteria are equal. Ended up writing a
function that builds a comparison operator by nesting ternary operators for each field, then using
that function in usort(). Hopefully it's of use to someone else.
/*
* Sorts an array of objects by a list of properties.
* Each property can have the following options:
* 'property' can be either a public variable or a method().
* 'order' can be ASC or DESC
* 'comparer' can be string, number, or date
*
* Example:
* sortObjectsByProperties($objects, array(
* array('property'=>'getPrice()', order=>'ASC',
'comparer'=>'number'),
* array('property'=>'getName()', order=>'DESC',
'comparer'=>'string'),
* array('property'=>'created_date', order=>'ASC',
'comparer'=>'date'),
* array('property'=>'id', order=>'ASC',
'comparer'=>'number'),
* ));
*
* @author Tyler Chamberlain
*/
function sortObjectsByProperties(&$objects, $fields) {
$comparerFunctionString = "";
foreach ($fields as $field) {
if ($field['comparer'] == 'number') {
$comparerFunction = "(\$a->{$field['property']} ==
\$b->{$field['property']} ? 0 : (\$a->{$field['property']} >
\$b->{$field['property']} ? 1 : -1))";
} elseif ($field['comparer'] == 'date') {
$comparerFunction = "(strtotime(\$a->{$field['property']}) >
strtotime(\$b->{$field['property']}) ? 1 : -1)";
} else {
$comparerFunction =
"strcasecmp(\$a->{$field['property']},\$b->{$field['property']})";
}
if ($field['order'] === 'DESC') { $comparerFunction =
"-".$comparerFunction; }
$comparerFunctionString .= "$comparerFunction != 0 ? $comparerFunction : (";
}
$comparer = "return ($comparerFunctionString 0 )".str_repeat(")",
sizeof($fields)).";";
usort($objects, create_function('$a,$b', $comparer));
}
http://php.net/manual/en/function.usort.php