PHP使用使用者自定義的比較函式對陣列中的值進行排序
原文:PHP 使用使用者自定義的比較函式對陣列中的值進行排序
usort
(PHP 4, PHP 5)
usort — 使用使用者自定義的比較函式對陣列中的值進行排序
說明
&$array
, callable $cmp_function
)
本函式將用使用者自定義的比較函式對一個陣列中的值進行排序。如果要排序的陣列需要用一種不尋常的標準進行排序,那麼應該使用此函式。
Note:
如果兩個成員比較結果相同,則它們在排序後的陣列中的順序未經定義。
Note: 此函式為
array
中的元素賦與新的鍵名。這將刪除原有的鍵名,而不是僅僅將鍵名重新排序。
引數
-
array
-
輸入的陣列
-
cmp_function
-
在第一個引數小於,等於或大於第二個引數時,該比較函式必須相應地返回一個小於,等於或大於 0 的整數。
CautionReturning non-integer values from the comparison function, such as float, will result in an internal cast to integer of the callback`s return value. So values such as 0.99 and 0.1 will both be cast to an integer value of 0, which will compare such values as equal.
返回值
成功時返回 TRUE
, 或者在失敗時返回 FALSE
。
更新日誌
版本 | 說明 |
---|---|
4.1.0 | 引進了新的排序演算法。使用者自定義函式 cmp_function 將不再保留這些單元的原有順序。 |
範例
Example #1 usort() 例子
<?php function cmp($a, $b)
{
if ($a == $b)
{ return 0; }
return ($a < $b) ? -1 : 1; }
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
foreach ($a as $key => $value)
{ echo "$key: $value
"; } ?>
以上例程會輸出:
0: 1 1: 2 2: 3 3: 5 4: 6
Note:
很明顯在這個小例子中用 sort() 函式更合適。
Example #2 使用多維陣列的 usort() 例子
<?php
function cmp($a, $b)
{ return strcmp($a["fruit"], $b["fruit"]); }
$fruits[0]["fruit"] = "lemons"; $fruits[1]["fruit"] = "apples"; $fruits[2]["fruit"] = "grapes";
usort($fruits, "cmp");
while (list($key, $value) = each($fruits))
{ echo "$fruits[$key]: " . $value["fruit"] . "
"; } ?>
當排序多維陣列時,$a 和 $b 包含到陣列第一個索引的引用。
以上例程會輸出:
$fruits[0]: apples $fruits[1]: grapes $fruits[2]: lemons
Example #3 usort() example using a member function of an object
<?php class TestObj { var $name; function TestObj($name) { $this->name = $name; } /* This is the static comparing function: */ static function cmp_obj($a, $b) { $al = strtolower($a->name); $bl = strtolower($b->name); if ($al == $bl) { return 0; } return ($al > $bl) ? +1 : -1; } } $a[] = new TestObj("c"); $a[] = new TestObj("b"); $a[] = new TestObj("d"); usort($a, array("TestObj", "cmp_obj")); foreach ($a as $item) { echo $item->name . " "; } ?>
以上例程會輸出:
b c d
Example #4 usort() example using a closure to sort a multi-dimensional array
<?php
$array[0] = array(`key_a` => `z`, `key_b` => `c`);
$array[1] = array(`key_a` => `x`, `key_b` => `b`);
$array[2] = array(`key_a` => `y`, `key_b` => `a`);
function build_sorter($key)
{ return function ($a, $b) use ($key)
{ return strnatcmp($a[$key], $b[$key]); }; }
usort($array, build_sorter(`key_b`));
foreach ($array as $item)
{ echo $item[`key_a`] . `, ` . $item[`key_b`] . "
"; } ?>
以上例程會輸出:
y, a x, b z, c
使用者評論:
Hayley Watson (2013-04-08 22:30:19)
As the documentation says, the comparison function needs to return an integer that is either "less than, equal to, or greater than zero". There is no requirement to restrict the value returned to -1, 0, 1.
<?php usort($array, function($a, $b) { if($a->integer_property > $b->integer_property) { return 1; } elseif($a->integer_property < $b->integer_property) { return -1; } else { return 0; } }); ?> can be simplified to
<?php usort($array, function($a, $b) { return $a->integer_property - $b->integer_property; }); ?> This of course applies to any comparison function that calculates an integer "score" for each of its arguments to decide which is "greater".
hexarobi at gmail dot com (2013-02-21 21:04:32)
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));
}
?>
Jian Wu (2012-07-06 21:16:20)
The usort function actually moves $b up when the callback function returns both 0 and 1. If you want to preserve the original order in the array, return 1 when $a == $b instead of 0. Try this code below to see how usort alters the order of the original array when all values are the same.
<?php
class TestObj {
private $name;
private $id;
function TestObj($name, $id) {
$this->name = $name;
$this->id = $id;
}
static function cmp_obj($a, $b) {
$al = strtolower($a->name);
$bl = strtolower($b->name);
if ($al == $bl) {
return 0; // return 1 if you don`t want $b to go in front of $a
}
return ($al > $bl) ? +1 : -1;
}
}
$a[] = new TestObj("a", 1);
$a[] = new TestObj("a", 2);
$a[] = new TestObj("a", 3);
var_dump($a);
usort($a, array("TestObj", "cmp_obj"));
var_dump($a);
?>
zuallauz at gmail dot com (2012-03-29 21:56:45)
When trying to do some custom sorting with objects and an anonymous function it wasn`t entirely clear how this usort function works. I think it probably uses a quicksort in the background. Basically it actually moves the $b variable up or down in respect to the $a variable. It does NOT move the $a variable inside the callback function. This is key to getting your logic right in the comparisons.
If you return -1 that moves the $b variable down the array, return 1 moves $b up the array and return 0 keeps $b in the same place.
To test I cut down my code to sorting a simple array from highest priority to lowest.
<?php $priorities = array(5, 8, 3, 7, 3);
usort($priorities, function($a, $b) { if ($a == $b) { echo "a ($a) is same priority as b ($b), keeping the same
"; return 0; } else if ($a > $b) { echo "a ($a) is higher priority than b ($b), moving b down array
"; return -1; } else { echo "b ($b) is higher priority than a ($a), moving b up array
"; return 1; } });
echo "Sorted priorities:
"; var_dump($priorities); ?> Output:
b (8) is higher priority than a (3), moving b up array b (5) is higher priority than a (3), moving b up array b (7) is higher priority than a (3), moving b up array a (3) is same priority as b (3), keeping the same a (8) is higher priority than b (3), moving b down array b (8) is higher priority than a (7), moving b up array b (8) is higher priority than a (5), moving b up array b (8) is higher priority than a (3), moving b up array a (5) is higher priority than b (3), moving b down array a (7) is higher priority than b (5), moving b down array
Sorted priorities: array(5) { [0]=> int(8) [1]=> int(7) [2]=> int(5) [3]=> int(3) [4]=> int(3) }
andi_mclean at ntlworld dot com (2012-02-04 15:58:08)
I needed a sort method that would sort strings but take note of any numbers and would compare them as number. I also want to ignore any non alphanumerical characters.
Eg. Slot 1 Example Slot 10 Example Slot 2 Example
Should infact be Slot 1 Example Slot 2 Example Slot 10 Example
<?php function sort_with_numbers($a , $b) { $a = explode(` `,$a); $b = explode(` `,$b); $size = min(count($a), count($b)); for($index =0; $index < $size; ++$index) { $a1 = ereg_replace("[^A-Za-z0-9]", "",$a[$index]); $b1 = ereg_replace("[^A-Za-z0-9]", "",$b[$index]); $equal = 0; if (is_numeric($a1) && is_numeric($b1)) { $equal = $a1 - $b1; } else { $equal = strcasecmp($a1,$b1); } if ($equal < 0) { return -1; } if ($equal > 0) { return 1; } } return count($a) - count($b); } ?>
Quicker (2012-01-05 13:53:43)
This one may approve multisort performance dramatically.
I had a 100K-row-array with assoc keys and sub arrays, several MBs. Using usort hammered my dev box cpu for several minutes until I killed it.
My own assoc-version of [someone else`s code] did the same. Following Array-Indexing and sorting solution only took very few secs:
<?php
define(`funcname`,0);
define(`indexfieldinfuncparamspos`,1);
define(`funcparams`,2);
function array_index($dataarr,$field2funcarr){
$indexarr=array();
foreach($dataarr as $key=>$valarr) {
$currentindex=``;
foreach($field2funcarr as $fieldid=>$funcarr) if(is_array($funcarr)) {
$funcarr[funcparams][$funcarr[indexfieldinfuncparamspos]]= $valarr[$fieldid];
$currentindex.= call_user_func_array($funcarr[funcname],$funcarr[funcparams]).`_`;
} else $currentindex.= $valarr[$fieldid].`_`;
$indexarr[$currentindex]=$key;
}
return $indexarr;
}
function array_sortbyindex(&$dataarr,$indexarr,$issortindexbykey=true){
// assumes complete index!: each item of indexarr must correlate a key of dataarr
$resultarr=array();
if($issortindexbykey) ksort($indexarr);
foreach($indexarr as $datakey) $resultarr[$datakey]= $dataarr[$datakey];
return $resultarr;
}
$dataarr=array(
`Franz`=>array(`letters`=>5,`wordtype`=>`name`),
`goes`=>array(`letters`=>4,`wordtype`=>`verb`),
`to`=>array(`letters`=>2,`wordtype`=>`prep`),
`China`=>array(`letters`=>5,`wordtype`=>`noun`));
// just build an index for interest (empty string for wordtype as no modification required):
print_r(array_index($dataarr, array(`letters`=>array(`str_pad`,0,array(``,7,`0`,STR_PAD_LEFT)), `wordtype`=>``)));
// build index and sort - all in one go:
print_r(array_sortbyindex($dataarr, array_index($dataarr, array(`letters`=>array(`str_pad`,0, array(``,7,`0`,STR_PAD_LEFT)), `wordtype`=>``))));
?>
first print_r returns:
Array
(
[0000005_name_] => Franz
[0000004_verb_] => goes
[0000002_prep_] => to
[0000005_noun_] => China
)
second print_r returns:
Array
(
[to] => Array
(
[letters] => 2
[wordtype] => prep
)
[goes] => Array
(
[letters] => 4
[wordtype] => verb
)
[Franz] => Array
(
[letters] => 5
[wordtype] => name
)
[China] => Array
(
[letters] => 5
[wordtype] => noun
)
)
Major Benefits:
- extremly fast
- each sort field can apply an own modifier. Ideally you can use out-of-the-box functions, which reduces effort for programming callbacks
- you could use the index eg. for sorted data output without physically sorting the data
admin at gosenz dot com (2011-12-04 20:58:38)
sort multi-dimentional arrays in class with usort
<?php class ArraySort { private $arr = array();
public function __construct($arr) { $this->arr = $arr; }
public function doSort() { $cmp = function($a, $b) { //Do Some Comparation } if(is_array($this->arr)) { usort($this->arr, $cmp); } return $this->arr; } } ?>
Gok6tm (2011-09-13 06:09:10)
this is a new multisort function for sorting on multiple subfield like it will be in sql : `ORDER BY field1, field2`
number of sort field is undefined
<?php
$array[] = array(`soc` => 3, `code`=>1);
$array[] = array(`soc` => 2, `code`=>1);
$array[] = array(`soc` => 1, `code`=>1);
$array[] = array(`soc` => 1, `code`=>1);
$array[] = array(`soc` => 2, `code`=>5);
$array[] = array(`soc` => 1, `code`=>2);
$array[] = array(`soc` => 3, `code`=>2);
//usage
print_r(multiSort($array, `soc`, `code`));
function multiSort() {
//get args of the function
$args = func_get_args();
$c = count($args);
if ($c < 2) {
return false;
}
//get the array to sort
$array = array_splice($args, 0, 1);
$array = $array[0];
//sort with an anoymous function using args
usort($array, function($a, $b) use($args) {
$i = 0;
$c = count($args);
$cmp = 0;
while($cmp == 0 && $i < $c)
{
$cmp = strcmp($a[ $args[ $i ] ], $b[ $args[ $i ] ]);
$i++;
}
return $cmp;
});
return $array;
}
?>
output:
Array
(
[0] => Array
(
[soc] => 1
[code] => 1
)
[1] => Array
(
[soc] => 1
[code] => 1
)
[2] => Array
(
[soc] => 1
[code] => 2
)
[3] => Array
(
[soc] => 2
[code] => 1
)
[4] => Array
(
[soc] => 2
[code] => 5
)
[5] => Array
(
[soc] => 3
[code] => 1
)
[6] => Array
(
[soc] => 3
[code] => 2
)
)
neculitairinel at yahoo dot com (2011-08-19 06:12:51)
Here is another date sort, in case you have hours and minutes in the dates.
<?php
function DateSort($a,$b,$d="-") {
if ($a == $b) {
return 0;
} else {
$a = strtotime($a);
$b = strtotime($b);
if($a<$b) {
return -1;
} else {
return 1;
}
}
}
?>
Lea Hayes (2011-07-12 17:55:13)
<?php
/**
* Sort array of objects by field.
*
* @param array $objects Array of objects to sort.
* @param string $on Name of field.
* @param string $order (ASC|DESC)
*/
function sort_on_field(&$objects, $on, $order = `ASC`) {
$comparer = ($order === `DESC`)
? "return -strcmp($a->{$on},$b->{$on});"
: "return strcmp($a->{$on},$b->{$on});";
usort($objects, create_function(`$a,$b`, $comparer));
}
?>
bcsj (2011-06-28 11:12:43)
Sorting a multidimensional array by a subkey seem to be one of the bigger challenges when using usort. At least if one want the key to be dynamic. For anyone interested this code seemed to work rather well for me:
<?php
usort($array,array(new cmp($key), "cmp__"));
class cmp { var $key; function __construct($key) { $this->key = $key; } function cmp__($a,$b) { $key = $this->key; if ($a[$key] == $b[$key]) return 0; return (($a[$key] > $b[$key]) ? 1 : -1); } }
?>
masonswolf+ignorethispart at gmail dot com (2011-06-13 10:42:03)
[The second version of a function I wrote], just a little cleaner to use, since the usort call is now folded into the custom `usortByArrayKey` function.
Seems like this is a popular problem - sorting an array of arrays by the keys of sub-arrays, so I`ll go ahead and throw in an approach I haven`t seen anyone mention yet. It only works since PHP 5.3 because that`s when anonymous functions got added to the language.
<?php
function usortByArrayKey(&$array, $key, $asc=SORT_ASC) {
$sort_flags = array(SORT_ASC, SORT_DESC);
if(!in_array($asc, $sort_flags)) throw new InvalidArgumentException(`sort flag only accepts SORT_ASC or SORT_DESC`);
$cmp = function(array $a, array $b) use ($key, $asc, $sort_flags) {
if(!is_array($key)) { //just one key and sort direction
if(!isset($a[$key]) || !isset($b[$key])) {
throw new Exception(`attempting to sort on non-existent keys`);
}
if($a[$key] == $b[$key]) return 0;
return ($asc==SORT_ASC xor $a[$key] < $b[$key]) ? 1 : -1;
} else { //using multiple keys for sort and sub-sort
foreach($key as $sub_key => $sub_asc) {
//array can come as `sort_key`=>SORT_ASC|SORT_DESC or just `sort_key`, so need to detect which
if(!in_array($sub_asc, $sort_flags)) { $sub_key = $sub_asc; $sub_asc = $asc; }
//just like above, except `continue` in place of return 0
if(!isset($a[$sub_key]) || !isset($b[$sub_key])) {
throw new Exception(`attempting to sort on non-existent keys`);
}
if($a[$sub_key] == $b[$sub_key]) continue;
return ($sub_asc==SORT_ASC xor $a[$sub_key] < $b[$sub_key]) ? 1 : -1;
}
return 0;
}
};
usort($array, $cmp);
};
?>
Examples:
1) Sort a multi-dimensional array by a single key, from least to greatest:
usortByArrayKey($resultset, `order_id`);
2) Sort a multi-dimensional array by a single key, from greatest to least:
usortByArrayKey($resultset, `purchase_amount`, SORT_DESC);
3) Sort a multi-dimensional array first by one key, but then by a different key when the first one is equal, both from least to greatest:
usortByArrayKey($resultset, array(`product_id`, `price`));
4) Sort a multi-dimensional array by two different keys from least to greatest, and then a third from greatest to least if the first two keys map to the equal values:
usortByArrayKey($resultset, array(`product_id`, `customer_id`, `date`=>SORT_DESC));
5) Sort a multi-dimensional array by multiple keys, all from greatest to least:
usortByArrayKey($resultset, array(`product_id`, `price`), SORT_DESC);
One word of caution, since SORT_ASC and SORT_DESC have actual int values of 4 and 3, respectively, if you need to sort a multi-dimensional array by keys 3 or 4, and you`re using an array to pass in your keys, you MUST specify your sort flags (e.g. array(3 => SORT_ASC,...)) to prevent unexpected behavior, instead of relying on the function`s second parameter as your default sort flag.
cuonghuyto at gmail dot com (2011-03-02 02:42:09)
Some contribution towards a specification of usort()
——
– If you don`t provide the callback function, an error would be raised: “usort(): Invalid comparison function.”
– If your callback function doesn`t return anything, or returns any value other than -1 or +1 (e.g. 0, 2, -2), then usort() would treat your sorting purpose as if there is no comparison operator provided, and it would actually change your list into an undefined order
——
markfiend at gmail dot com (2011-02-21 02:22:41)
To sort a multidimensional array (such as is returned from database query) by the values in $array[foo][$key]
e.g. <?php /** Potential pitfall if there is already a key of `__________` * in the subarrays. Not likely I hope! * ------------------------------------------------------------- */ function array_sort_by_subval(&$array, $key) { foreach($array as &$v) { $v[`__________`] = $v[$key]; } usort($array, `sort_by_underscores`); foreach($array as &$v) { unset($v[`__________`]); } }
function sort_by_underscores($a, $b) { if($a[`__________`] == $b[`__________`]) return 0; if($a[`__________`] < $b[`__________`]) return -1; return 1; }
$n = array(array(`a` => 0, `b` => 7, `c` => 2), array(`a` => 4, `b` => 1, `c` => 3), array(`a` => 7, `b` => 3, `c` => 1));
array_sort_by_subval($n, `b`); ?> The array $n will now be: array(array(`a` => 4, `b` => 1, `c` => 3), array(`a` => 7, `b` => 3, `c` => 1), array(`a` => 0, `b` => 7, `c` => 2))
cmanley_nl (2011-01-24 11:55:40)
I had to sort a result set by host. I made this comparator function to use in usort calls.
Sorts by host segment so that a.example.org comes after b.example.com, etc.
<?php
function hostcmp($a, $b) {
$a = strtolower($a);
$b = strtolower($b);
if ($a == $b) {
return 0;
}
$parts_a = array_reverse(explode(`.`, $a));
$parts_b = array_reverse(explode(`.`, $b));
$max = max(count($parts_a), count($parts_b));
for ($i=0; $i < $max; $i++) {
if (($i < count($parts_a)) && ($i < count($parts_b))) {
if ($c = strcmp($parts_a[$i],$parts_b[$i])) {
return $c;
}
}
else {
// Return numeric cmp on array sizes. PHP doesn`t have a <=> operator, so emulate it.
//return count($parts_a) <=> count($parts_b);
return count($parts_a) == count($parts_b) ? 0 : (count($parts_a) < count($parts_b) ? -1 : 1);
}
}
return 0;
}
?>
fmaz008 at gmail dot com (2010-09-29 14:23:36)
This comment is just to help backward compatibility.
I needed to have a foreach loop using reference just before using the usort function on the same array that was used in the foreach.
Like this: <?php public function sortByTitle() { if(empty($this->_arrSubCat)) return false; foreach($this->_arrSubCat as &$cat) $cat->sortByTitle(); usort($this->_arrSubCat, `strcasecmp`); } ?> I had this strange bug where the last object of the $this->_arrSubCat array before the sort was alway replaced/overwrited with his string value.
On my machine (PHP 5.3), I had no problem, but when I placed the code on another server, my code crashed with a fatal error (Because I was using a string as an object later in the code)
The solution I found is really simple, and avoid the array to have a reference declared in memory while running the sort function. Just add an unset($cat):
<?php public function sortByTitle() { if(empty($this->_arrSubCat)) return false; foreach($this->_arrSubCat as &$cat) $cat->sortByTitle(); unset($cat); //No more problem because of the foreach &cat reference. usort($this->_arrSubCat, `strcasecmp`); } ?> It took me an hour an a half to locate the bug, hope it will save someone some time !
phil at lavin dot me dot uk (2010-08-01 11:06:07)
strcmp (or strcasecmp) can be used as a callback function for usort. It will cast your comparison values to string. Thus, you can implement a __toString() method into your classes and use usort without creating a callback function:
<?php class Foo { private $a; private $b;
public function __construct($a, $b) { $this->a = $a; $this->b = $b; }
public function __toString() { return (string)$this->a; } }
$foo = array(new Foo(`t`, `b`), new Foo(`a`, `c`), new Foo(`g`, `d`));
print_r($foo);
usort($foo, `strcasecmp`);
print_r($foo); ?>
xaguilars at gmail dot com (2010-05-06 04:03:29)
I`d like to share with the community my function for sorting an array of arrays or objects containing associative data. This could be used, for example, with a MySQL result.
<?php function sort_by($field, &$arr, $sorting=SORT_ASC, $case_insensitive=true){ if(is_array($arr) && (count($arr)>0) && ( ( is_array($arr[0]) && isset($arr[0][$field]) ) || ( is_object($arr[0]) && isset($arr[0]->$field) ) ) ){ if($case_insensitive==true) $strcmp_fn = "strnatcasecmp"; else $strcmp_fn = "strnatcmp";
if($sorting==SORT_ASC){ $fn = create_function(`$a,$b`, ` if(is_object($a) && is_object($b)){ return `.$strcmp_fn.`($a->`.$field.`, $b->`.$field.`); }else if(is_array($a) && is_array($b)){ return `.$strcmp_fn.`($a["`.$field.`"], $b["`.$field.`"]); }else return 0; `); }else{ $fn = create_function(`$a,$b`, ` if(is_object($a) && is_object($b)){ return `.$strcmp_fn.`($b->`.$field.`, $a->`.$field.`); }else if(is_array($a) && is_array($b)){ return `.$strcmp_fn.`($b["`.$field.`"], $a["`.$field.`"]); }else return 0; `); } usort($arr, $fn); return true; }else{ return false; } } ?>
Alex Rath (2010-04-17 11:35:51)
This is the perfect Place for anonymous Functions, here an Example:
<?php
$array = array(3, 2, 5, 6, 1);
usort($array, function($func_a, $func_b) { if($func_a == $func_b) return 0; return ($func_a < $func_b) ? -1 : 1; });
foreach ($array as $key => $value) echo "$key: $value
";
?>
nicolas dot demarque at gmail dot com (2010-04-10 11:37:09)
Another way to compare object is to have a compare static function in the class with reccursion ability and have globals or static variables who save the state of comparison, and the order.
It could be a good idea to have a variable with comparison functions name (with the sorting : numeric, alphanumeric, inverse).
<?php interface Comparable{static function compare($a, $b);} class myObj implements Comparable{ var $var1; var $var2; var $var3; function __construct($v1, $v2, $v3){ $this->var1=$v1; $this->var2=$v2; $this->var3=$v3; } public function __toString() { return "v1 ".$this->var1." v2 ".$this->var2." v3 ".$this->var3; } static function compare($a, $b){ $sort=$GLOBALS[`sorts`][$GLOBALS[`sort`]]; echo "$sort
"; if($a->$sort == $b->$sort){ if($GLOBALS[`sorts`][$GLOBALS[`sort`]+1]){ $GLOBALS[`sort`]++; $res= call_user_func(array(`myObj`, `compare`), $a, $b); $GLOBALS[`sort`]=0; return $res; } $GLOBALS[`sort`]=0; return 0; } $GLOBALS[`sort`]=0; if($a->$sort > $b->$sort) return 1; return -1; } }
$objects = array(new myObj("1", "2", "3"), new myObj("2", "2", "2"), new myObj("1", "3", "4"));
/* Tests */ $sorts=Array(`var1`, `var2`, `var3`); $sort = 0; usort($objects, array(`myObj`, `compare`)); echo ("var1 var2 var3
"); foreach($objects as $o)echo $o."
"; $sorts=Array(`var2`, `var3`, `var1`); $sort = 0; usort($objects, array(`myObj`, `compare`)); echo ("
var2 var3 var1
"); foreach($objects as $o)echo $o."
"; $sorts
相關文章
- ***PHP陣列排序+php二維陣列排序方法(PHP比較器)PHP陣列排序
- 陣列排序函式-php陣列函式(一)陣列排序函式PHP
- stl中各種容器的自定義比較函式函式
- PHP開發之自定義函式及陣列PHP函式陣列
- iOS中對NSArray中自定義的物件進行排序iOS物件排序
- cmp是可選的自定義比較函式函式
- JavaScript 使用sort()方法從數值上對陣列進行排序JavaScript陣列排序
- PHP的的陣列和比較符PHP陣列
- js:陣列自定義排序JS陣列排序
- 1122. 陣列的相對排序(計數排序 / 自定義排序)陣列排序
- 二維陣列根據鍵的值進行排序陣列排序
- 陣列二:使用陣列可變函式為陣列排序陣列函式排序
- 使用頻率比較高的PHP函式方法PHP函式
- 陣列進行排序的方法陣列排序
- Js比較對Object型別進行排序JSObject型別排序
- Arr::sort()輔助函式對多維陣列的排序函式陣列排序
- js實現的陣列自定義排序介紹JS陣列排序
- 根據陣列中物件進行排序陣列物件排序
- Clickhouse 使用者自定義外部函式函式
- HIVE中的自定義函式Hive函式
- Javascript陣列排序sort方法和自定義排序方法JavaScript陣列排序
- PHP 陣列常用函式PHP陣列函式
- 巧用 PHP 陣列函式PHP陣列函式
- PHP 陣列函式妙用PHP陣列函式
- Java、C、C++中的陣列的比較JavaC++陣列
- PHP 多維陣列排序-按某個 key 的值PHP陣列排序
- Loadrunner 使用者自定義函式使用[轉]函式
- 對自定義函式使用不當的調優案例函式
- PHP:常用PHP陣列操作函式PHP陣列函式
- 《每天用對比的思想學點 golang》PHP 對比有意思的 go-定義函式,定義返回值型別GolangPHP函式型別
- 歸併排序-陣列中的逆序對排序陣列
- python 對字典的值進行排序Python排序
- php陣列函式小結PHP陣列函式
- PHP陣列函式彙總PHP陣列函式
- Qt自定義動畫插值函式QT動畫函式
- PHP 自定義函式用法及常用函式集合PHP函式
- 排序(對於 sort 函式的使用)排序函式
- 一對一直播軟體原始碼,比較常用的陣列排序方式有哪些?原始碼陣列排序