Sort multi-dimensional array with usort

家住魔仙堡 提交于 2019-12-24 09:58:56

问题


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


来源:https://stackoverflow.com/questions/6286337/sort-multi-dimensional-array-with-usort

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!