开发者

Sort multi-dimensional array with usort

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
     re开发者_高级运维turn -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!!


Why don't you directly use strcmp function?

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜