note 89977 added to function.usort
| From: | gmail dot com-nmcquay at osu1 dot php dot net | Date: | Tue, 31 Mar 2009 20:25:10 +0000 |
| Subject: | note 89977 added to function.usort | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-152664@lists.php.net to get a copy of this message | ||
I wrote a wrapper for usort that lets you use something similar to an SQL ORDER BY clause. It can
sort arrays of associative arrays and arrays of objects and I think it would work with some hybrid
case.
Example of how the function works:
$testAry = array(
array('a' => 1, 'b' => 2, 'c' => 3),
array('a' => 2, 'b' => 1, 'c' => 3),
array('a' => 3, 'b' => 2, 'c' => 1),
array('a' => 1, 'b' => 3, 'c' => 2),
array('a' => 2, 'b' => 3, 'c' => 1),
array('a' => 3, 'b' => 1, 'c' => 2)
);
Utility::orderBy($testAry, 'a ASC, b DESC');
//Result:
$testAry = array(
array('a' => 1, 'b' => 3, 'c' => 2),
array('a' => 1, 'b' => 2, 'c' => 3),
array('a' => 2, 'b' => 3, 'c' => 1),
array('a' => 2, 'b' => 1, 'c' => 3),
array('a' => 3, 'b' => 2, 'c' => 1),
array('a' => 3, 'b' => 1, 'c' => 2)
);
To sort an array of objects you would do something like:
Utility::orderBy($objectAry, 'getCreationDate() DESC, getSubOrder() ASC');
This would sort an array of objects that have methods getCreationDate() and getSubOrder().
Here is the function:
class Utility {
/*
* @param array $ary the array we want to sort
* @param string $clause a string specifying how to sort the array similar to SQL ORDER BY clause
* @param bool $ascending that default sorts fall back to when no direction is specified
* @return null
*/
public static function orderBy(&$ary, $clause, $ascending = true) {
$clause = str_ireplace('order by', '', $clause);
$clause = preg_replace('/\s+/', ' ', $clause);
$keys = explode(',', $clause);
$dirMap = array('desc' => 1, 'asc' => -1);
$def = $ascending ? -1 : 1;
$keyAry = array();
$dirAry = array();
foreach($keys as $key) {
$key = explode(' ', trim($key));
$keyAry[] = trim($key[0]);
if(isset($key[1])) {
$dir = strtolower(trim($key[1]));
$dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
} else {
$dirAry[] = $def;
}
}
$fnBody = '';
for($i = count($keyAry) - 1; $i >= 0; $i--) {
$k = $keyAry[$i];
$t = $dirAry[$i];
$f = -1 * $t;
$aStr = '$a[\''.$k.'\']';
$bStr = '$b[\''.$k.'\']';
if(strpos($k, '(') !== false) {
$aStr = '$a->'.$k;
$bStr = '$b->'.$k;
}
if($fnBody == '') {
$fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
$fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
} else {
$fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
$fnBody .= "}\n";
$fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
}
}
if($fnBody) {
$sortFn = create_function('$a,$b', $fnBody);
usort($ary, $sortFn);
}
}
}
----
Server IP: 64.71.164.2
Probable Submitter: 65.46.255.194
----
Manual Page -- http://www.php.net/manual/en/function.usort.php
Edit -- https://master.php.net/note/edit/89977
Del: integrated -- https://master.php.net/note/delete/89977/integrated
Del: useless -- https://master.php.net/note/delete/89977/useless
Del: bad code -- https://master.php.net/note/delete/89977/bad+code
Del: spam -- https://master.php.net/note/delete/89977/spam
Del: non-english -- https://master.php.net/note/delete/89977/non-english
Del: in docs -- https://master.php.net/note/delete/89977/in+docs
Del: other reasons-- https://master.php.net/note/delete/89977
Reject -- https://master.php.net/note/reject/89977
Search -- https://master.php.net/manage/user-notes.php