Reputation: 8405
Hey guys I'm trying to reverse sort a multidimensional array with usort but am messing up somewhere. Here's my code:
$array = array(
array(123 => 'foo'), // duplicate
array(124 => 'foo'),
array(127 => 'foo'),
array(126 => 'foo'),
array(123 => 'foo'), // duplicate
array(125 => 'foo'),
);
function rcmp($a, $b) {
if($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
usort($array, 'rcmp');
print_r($array);
/*
Array
(
[0] => Array ( [126] => foo) )
[1] => Array ( [125] => foo) )
[2] => Array ( [127] => foo) )
[3] => Array ( [123] => foo) )
[4] => Array ( [124] => foo) )
[5] => Array ( [123] => foo) )
)
*/
I am expecting
/*
Array
(
[0] => Array ( [127] => foo) )
[1] => Array ( [126] => foo) )
[2] => Array ( [125] => foo) )
[3] => Array ( [124] => foo) )
[4] => Array ( [123] => foo) )
[5] => Array ( [123] => foo) )
)
*/
What am I doing wrong?
Upvotes: 0
Views: 234
Reputation: 8405
Here's a solution using create_function
that I came up with, accepting the best answer though. Thanks and hope this helps someone else out.
$array = array(
array(124 => 'foo'),
array(123 => 'foo'), // duplicate
array(127 => 'foo'),
array(126 => 'foo'),
array(123 => 'foo'), // duplicate
array(125 => 'foo'),
);
usort($array, create_function('$a, $b','return (key($a) == key($b))
? 0
: (key($a) < key($b))
? -1
: 1;'));
print_r($array);
Upvotes: 0
Reputation: 74078
If you want to compare on the array's indexes, you must extract the indexes in the comparison function and reverse the comparison for descending order
function rcmp($a, $b) {
$a = array_keys($a);
$b = array_keys($b);
if($a[0] == $b[0]) {
return 0;
}
return ($a[0] < $b[0]) ? 1 : -1;
}
Upvotes: 2
Reputation: 437574
When your comparison function rcmp
is invoked, its arguments $a
and $b
are arrays so your equality and less-than operators have arrays as their operands.
The equality operator on arrays works like this:
TRUE if $a and $b have the same key/value pairs.
The less-than comparison works like this:
Array with fewer members is smaller, if key from operand 1 is not found in operand 2 then arrays are uncomparable, otherwise - compare value by value.
"Uncomparable" means the comparison evaluates to null
, which in turn causes rcmp
to return 1
.
So what ends up happening is that when $a
and $b
are not identical arrays rcmp
always returns 1 (i.e. considers that $a
is greater). This happens irrespective of what the key in each array is, and as a result you get a meaningless ordering.
If you wanted to order these arrays by their first key with usort
, you would do it like this:
function rcmp($a, $b)
{
return key($a) - key($b);
}
Upvotes: 2