dongzhitao4839 2016-03-18 06: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 06: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条)
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部