note 89977 added to function.usort

From: 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

« previous php.notes (#152664) next »