Sort multi-dimensional array with usort

2019-08-15 03:21发布

问题:

The following usort function does not always give the right result since it will only "push" up or down one position relative to the compared item. Thus when performing the sort multiple times the result Yes No Yes Nocan occur.

The function successfully sort field b.

How can I solve this?

array

[0] => array("a"=>"Yes","b"=>"apple"...);
[1] => array("a"=>"Yes","b"=>"banana"...);
[2] => array("a"=>"No","b"=>"lemon"...);
[3] => array("a"=>"No","b"=>"grape"...);
...

current function

function sortAnserDesc($x, $y){
    if ( $x['a'] == $y['a'] )
     return 0;
    else if ( $x['a'] < $y['a'] )
     return 1;
    else
     return -1;
}

回答1:

I found a very good function on http://www.php.net/manual/en/function.usort.php#103722 And I think you have a general problem.

I try to display the callback function for usort here.

 function usortByArrayKey($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');

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

And to integrate with your code, you might have something like:

  1. Sorting a value only by DESCENDING.

    usort($YOUR_ARRAY, usortByArrayKey('a', SORT_DESC));

  2. Sorting a and b.

    usort($YOUR_ARRAY, usortByArrayKey(array('a', 'b')));

  3. More on sorting a and b by DESCENDING

    usort($YOUR_ARRAY, usortByArrayKey(array('a', 'b')), SORT_DESC);

Hope this help!!



回答2:

Why don't you directly use strcmp function?

function sortAnserDesc($x, $y){
    return strcmp($x['a'],$y['a']);
}


标签: php usort