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?

有帮助吗?

解决方案 2

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;
}

其他提示

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);
}

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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top