dongliaojing0554 2018-08-09 18:48
浏览 30

PHP按strnatcmp和另一个特定关键字排序

  • I need to sort an multi dimensional array which looks like this down below (usort already applied).
  • I need to move '10000_M3' to the first key if an identifier '_M' was found (as natural sorting), but the order from 'first' sort should not be touched.
  • Extra: (Optional) If i have a description like '10000_0', it should be still in index 0
  • If the usort can be done in 1 step would be great
  • I take any solution (usort, foreach, ..)!!!

    usort($anArray, function ($a, $b) {
        return strnatcmp($a['description'], $b['description']);
    });
    
    $anArray = [
        // ? => [
        //     'description' => '10000_0'
        // ]
        0 => [
            'description' => '10000_D2'
        ],
        1 => [
            'description' => '10000_D3'
        ],
        2 => [
            'description' => '10000_M3'
        ],
        3 => [
            'description' => '10000_M4'
        ]
    ]
    

Result (Natural -> at first position = '_0' -> $ident = '_M' after '_0' if its exists):

    $result = [
        0 => [
            'description' => '10000_0'
        ]
        1 => [
            'description' => '10000_M3'
        ],
        2 => [
            'description' => '10000_M4'
        ]
        3 => [
            'description' => '10000_D2'
        ],
        4 => [
            'description' => '10000_D3'
        ],
    ]
  • 写回答

2条回答 默认 最新

  • doukan3504 2018-08-09 19:39
    关注

    You can modify your sort function to check for the special cases individually then fall back on a regular sorting method.

    <?php
    $inputArray = [
        0 => [
            'description' => '10000_D2'
        ],
        1 => [
            'description' => '10000_D3'
        ],
        2 => [
            'description' => '10000_M3'
        ],
        3 => [
            'description' => '10000_M4'
        ],
        4 => [
             'description' => '10000_0'
        ]
    ];
    
    usort($inputArray, function ($a, $b) {
        // _0 first then _M* then alphabetic
    
        //assume only 1 value will be _0?
        if (preg_match('/_0$/', $a['description']) === 1){
            //"a" ends in _0
            return -1;
        }
        if (preg_match('/_0$/', $b['description']) === 1){
            //"b" ends in _0
            return 1;
        }
    
        if (
            preg_match('/_M\d*$/', $a['description']) === 1
            && preg_match('/_M\d*$/', $b['description']) === 1
        ){
            //both have "M" so sort them normally
            return strnatcmp($a['description'], $b['description']);
        }
    
        if (preg_match('/_M\d*$/', $a['description']) === 1){
            //only "a" has _M
            return -1;
        }
    
        if (preg_match('/_M\d*$/', $b['description']) === 1){
            //only "b" has _M
            return 1;
        }
    
        //neither side has _M or _0 so normal sorting
        return strnatcmp($a['description'], $b['description']);
    });
    
    echo print_r($inputArray, true);
    ?>
    

    Output:

    Array
    (
        [0] => Array
            (
                [description] => 10000_0
            )
    
        [1] => Array
            (
                [description] => 10000_M3
            )
    
        [2] => Array
            (
                [description] => 10000_M4
            )
    
        [3] => Array
            (
                [description] => 10000_D2
            )
    
        [4] => Array
            (
                [description] => 10000_D3
            )
    
    )
    

    I'm assuming you will only have a single _0 value. If you could have multiple _0 values then you need to modify the above code to behave like the 3 _M "if" statements.

    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号