dongzhitao4839 2016-03-18 14:39
浏览 18
已采纳

三维排序字符串数组PHP

I'm trying to order this multidimensional array, with no success. I need to sort ascending by pub_obs but keeping the main array order (AC, BA, ..). The indexes inside the main arrays (0, 1, 2, ..) can change but the pub_id have to be the same.

Array(
    [AC] => Array
        (
            [0] => Array
                (
                    [pub_id] => 1
                    [pub_obs] => c
                )
            [1] => Array
                (
                    [pub_id] => 3
                    [pub_obs] => a
                )
            [2] => Array
                (
                    [pub_id] => 4
                    [pub_obs] => c
                )
        )
    [BA] => Array
        (
            [0] => Array
                (
                    [pub_id] => 1
                    [pub_obs] => b
                )
            [1] => Array
                (
                    [pub_id] => 2
                    [pub_obs] => b
                )
            [2] => Array
                (
                    [pub_id] => 7
                    [pub_obs] => a
                )
        )
)

Somebody can help? Thanks!

Edit

I forgot to say about the PHP version, 5.2, but @fusion3k was quick! thanks for the answer dude and for everybody who helped too!

  • 写回答

2条回答 默认 最新

  • doulou1970 2016-03-18 14:58
    关注

    Use a foreach with main array by reference, then usort fore each row:

    foreach( $array as &$row )
    {
        usort
        (
            $row,
            function( $a, $b )
            {
                return strcmp($a['pub_obs'], $b['pub_obs']);
            }
        );
    }
    

    Output:

    Array
    (
        [AC] => Array
            (
                [0] => Array
                    (
                        [pub_id] => 3
                        [pub_obs] => a
                    )
    
                [1] => Array
                    (
                        [pub_id] => 4
                        [pub_obs] => c
                    )
    
                [2] => Array
                    (
                        [pub_id] => 1
                        [pub_obs] => c
                    )
    
            )
    
        [BA] => Array
            (
                [0] => Array
                    (
                        [pub_id] => 7
                        [pub_obs] => a
                    )
    
                [1] => Array
                    (
                        [pub_id] => 2
                        [pub_obs] => b
                    )
    
                [2] => Array
                    (
                        [pub_id] => 1
                        [pub_obs] => b
                    )
    
            )
    
    )
    

    Using references in the foreach the usort function act directly on main array, then in custom function compare pub_id keys to define nested sort order.

    Edit:

    The above method works, as requested in the question. However, if we have a sub-array like this one:

    [
        [ 'pub_id' => 1, 'pub_obs' => 'b' ],
        [ 'pub_id' => 2, 'pub_obs' => 'b' ],
        [ 'pub_id' => 3, 'pub_obs' => 'a' ]
    ]
    

    the output is:

    Array
    (
        [0] => Array
            (
                [pub_id] => 3
                [pub_obs] => a
            )
        [1] => Array
            (
                [pub_id] => 2
                [pub_obs] => b
            )
        [2] => Array
            (
                [pub_id] => 1
                [pub_obs] => b
            )
    )
    

    The requested keys are correctly sorted, but — on same pub_obs value — pub_id order is not maintained.

    To avoid this, you have to sub-process even the pub_id key:

        usort
        (
            $row,
            function( $a, $b )
            {
    
                $mainCmp = strcmp( $a['pub_obs'], $b['pub_obs'] );
                if( !$mainCmp )
                {
                    return( strcmp( $a['pub_id'], $b['pub_id'] ) );
                }
                else return $mainCmp;
            }
        );
    

    Using this solution in PHP < 5.3

    Simply define a custom function with same content of above anonymous function:

    function myCompare( $a, $b )
    {
    
        $mainCmp = strcmp( $a['pub_obs'], $b['pub_obs'] );
        if( !$mainCmp )
        {
            return( strcmp( $a['pub_id'], $b['pub_id'] ) );
        }
        else 
        return $mainCmp;
    }
    

    and then call it inside the foreach() loop:

    foreach( $array as &$row )
    {
        usort( $row, 'myCompare' );
    }
    

    <kbd>demo</kbd>



    PS: Thank you to @deceze for previous edit (maintained here).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 安装svn网络有问题怎么办
  • ¥15 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献