【问题标题】:sort array by multiple keys with optional key使用可选键按多个键对数组进行排序
【发布时间】:2026-02-05 07:05:02
【问题描述】:

以下数组包含来自更大数据集的数据样本 -

$data =
[
        [
                'readingSequence' => '35',
                'bookID' => '19',
                'chapter' => '130'
        ],
        [
                'readingSequence' => '19',
                'bookID' => '19',
                'chapter' => '27'
        ],
        [
                'readingSequence' => '59',
                'bookID' => '19',
                'chapter' => '133'
        ],
        [
                'readingSequence' => '35',
                'bookID' => '19',
                'chapter' => '129'
        ],
        [
                'readingSequence' => '98',
                'bookID' => '75',
                'chapter' => '6',
                'verses' => '11-20,',
                'versesFirst' => '11'
        ],
        [
                'readingSequence' => '99',
                'bookID' => '75',
                'chapter' => '6',
                'verses' => '1-10',
                'versesFirst' => '1'
        ]
];

该用例要求$data 的元素按bookID 排序,然后是chapter,如果该键存在则versesFirst

以下代码成功地按bookIDchapter 对数组进行排序,但我还没有找到一种方法也可以按versesFirst 排序,因为它存在于某些元素中,但不存在于其他元素中-

array_multisort(array_column($data, 'bookID'), SORT_ASC, array_column($data, 'chapter'), SORT_ASC, $data);

结果如下:

Array
(
    [0] => Array
        (
            [readingSequence] => 19
            [bookID] => 19
            [chapter] => 27
        )

    [1] => Array
        (
            [readingSequence] => 35
            [bookID] => 19
            [chapter] => 129
        )

    [2] => Array
        (
            [readingSequence] => 35
            [bookID] => 19
            [chapter] => 130
        )

    [3] => Array
        (
            [readingSequence] => 59
            [bookID] => 19
            [chapter] => 133
        )

    [4] => Array
        (
            [readingSequence] => 98
            [bookID] => 75
            [chapter] => 6
            [verses] => 11-20,
            [versesFirst] => 11
        )

    [5] => Array
        (
            [readingSequence] => 99
            [bookID] => 75
            [chapter] => 6
            [verses] => 1-10
            [versesFirst] => 1
        )

)

元素 0 到 3 排序正确,但元素 4 和 5 排序不正确,因为不包括 versesFirst。当尝试包含它时,会显示此警告,结果与上面显示的相同。

警告:array_multisort():数组大小在 C:\development\scratchpad.php 第 122 行不一致

我可以将[versesFirst] => '' 添加到没有versesFirst 键的元素中,这样它就可以包含在多排序中,但我不想这样做。有没有办法在多排序中包含可选键?或者是否有完全不同的方法来实现所需的结果集?

【问题讨论】:

    标签: php arrays sorting


    【解决方案1】:

    您可以使用usort 来完成此操作,并通过isset 检查versesFirst 键。

    片段:

    <?php
    
    usort($data, function($a,$b){
        $book_id_1 = intval($a['bookID']);
        $book_id_2 = intval($b['bookID']);
        
        if($book_id_1 != $book_id_2) return $book_id_1 <=> $book_id_2;
        
        $chapter_1 = intval($a['chapter']);
        $chapter_2 = intval($b['chapter']);
        
        if($chapter_1 != $chapter_2) return $chapter_1 <=> $chapter_2;
        
        if(!isset($b['versesFirst'])){
            return -1;
        }
        
        if(!isset($a['versesFirst'])){
            return 1;
        }
        
        return intval($a['versesFirst']) <=> intval($b['versesFirst']);
    });
    
    print_r($data);
    

    【讨论】:

      最近更新 更多