簡體   English   中英

如何在 PHP 5.4 版中使用鍵對多維數組進行排序?

[英]How to sort multidimensional array in PHP version 5.4 - with keys?

在這里問了一個非常相似的問題並得到了一個很好的答案。

但是后來我不得不對我的數組數據進行一次更改,它破壞了排序算法,我不知道為什么。

在上一個問題中,我的數組如下所示:

Array
(
    [0] => Array
        (
            [0] => Game
            [1] => Date
            [2] => Site
            [3] => Address
            [4] => FirstName
            [5] => LastName
            [6] => Email
            [7] => Phone
        )

    [1] => Array
        (
            [0] => B-Dry @ Blue Wave DH
            [1] => 7/9/2019 13:00
            [2] => Blue Wave Dover City Park
            [3] => Dover
            [4] => John
            [5] => Doe
            [6] => john.doe@perrylocal.org
            [7] => (555) 555-4797
        )

    [2] => Array
        (
            [0] => B-Dry @ Blue Wave DH
            [1] => 7/9/2019 13:00
            [2] => Blue Wave Dover City Park
            [3] => Dover
            [4] => Frank
            [5] => Sinatra
            [6] => frank@sinatra.com
            [7] => (555) 685-5555
        )

    [3] => Array
        (
            [0] => B-Dry @ Gnaden
            [1] => 6/7/2019 18:00
            [2] => Gnaden Indian Valley HS
            [3] => Gnadenhutten
            [4] => Jimmy
            [5] => Dean
            [6] => jimmy@dean.org
            [7] => (330) 555-5555
        )
   [...many more...]
)

並應用來自AymDev的以下排序算法AymDev進行了出色的排序:

$labelsRow = array_shift($cleanSheetArray);

$cleanSheetArray = array_map(
function ($cleanRowArray)
    {
    $cleanRowArray[1] = DateTime::createFromFormat('d/m/Y H:i', $cleanRowArray[1]);
    return $cleanRowArray;
    }

, $cleanSheetArray);

SortSheet($cleanSheetArray, 3);

function SortSheet(&$arr, $max_index = false, $index = 0) { // $index represents the number of columns to sort on, in order from the first column

    function mult_usort_callback($a, $b, $max_index, $index) {
        $max_index = $max_index ?: (count($a) - 1);

        // Recursively sort till the max index
        if ($a[$index] == $b[$index]) {
            if ($index < $max_index) {
                return mult_usort_callback($a, $b, $max_index, ($index + 1));
            } else {
                return 0;
            }
        }
        return $a[$index] > $b[$index] ? 1 : -1;
    };

    usort($arr, create_function('$a, $b', 'return mult_usort_callback($a, $b, ' . $max_index . ', ' . $index . ');'));
}

這對我的 multidim 數組進行排序,到目前為止一切都很完美。

但是后來我對數組結構進行了更改:

[151] => Array
    (
        [Game] => Kaufman @ B-Dry DH
        [Date] => DateTime Object
            (
                [date] => 2019-04-05 13:00:00.000000
                [timezone_type] => 3
                [timezone] => America/Denver
            )

        [Site] => B-Dry City Rec Park - Otsego Ave
        [Address] => Coshocton
        [FirstName] => Joe
        [LastName] => Barnes
        [Email] => redacted@yahoo.com
        [Phone] => (740) 000-0000
    )

[152] => Array
    (
        [Game] => Kaufman @ B-Dry DH
        [Date] => DateTime Object
            (
                [date] => 2019-04-05 13:00:00.000000
                [timezone_type] => 3
                [timezone] => America/Denver
            )
        [Site] => B-Dry Ridgewood High School
        [Address] => Coshocton
        [FirstName] => 
        [LastName] => 
        [Email] => 
        [Phone] => 
    )

[153] => Array
    (
        [Game] => Kaufman @ B-Dry DH
        [Date] => DateTime Object
            (
                [date] => 2019-04-05 13:00:00.000000
                [timezone_type] => 3
                [timezone] => America/Denver
            )
         [Site] => B-Dry City Rec Park - Otsego Ave
         [Address] => Coshocton
         [FirstName] => 
         [LastName] => 
         [Email] => 
         [Phone] => 
    )

請注意,我將鍵從索引器更改為列名。 這對我處理后期邏輯非常有幫助。 隨着此數據/密鑰更改,我嘗試更改日期對象化:

$cleanSheetArray = array_map(function ($cleanRowArray) {
    $cleanRowArray['Date'] = DateTime::createFromFormat('d/m/Y H:i', $cleanRowArray['Date']);
    return $cleanRowArray;
}, $cleanSheetArray);

從將字符串日期轉換為日期對象的角度來看,這似乎確實有效。 但它打破了排序。 您可以通過查看新數組的 3 個元素來查看排序中斷的證據。 觀察數組段 151 和 153 應該是連續的,因為游戲、日期和站點是相同的。 152沒有以151和152相同的值, GameDate都一樣,但Site是不同的。 在之前的數組結構(使用索引鍵而不是命名鍵)中,排序是正確的。

我懷疑我需要對SortSheet()函數進行某種更改,但我無法弄清楚它是什么。

重要說明:鍵名序列將始終相同。 換句話說,關鍵序列將始終是游戲,然后是日期,然后是站點等。因此該序列始終可以被計算在內。

有任何想法嗎?

使用以前的數字排序數組的快速修復可能是:

// Save the keys
$keys = array_shift($data);

/* here, do the sorting ... */

// Then apply the keys to your ordered array
$data = array_map(function ($item) {
    global $keys;
    return array_combine($keys, $item);
}, $data);

但是讓我們更新我以前的功能

function mult_usort_assoc(&$arr, $max_index = false, $index = false) {

    function mult_usort_callback($a, $b, $max_index, $index) {
        $max_index = $max_index ?: key(end($a));    // If not provided, takes last key
        $index     = $index ?: array_keys($a)[0];   // If not provided, takes first key

        // When data are equal, sort by next key only if not after the $max_index
        if ($a[$index] == $b[$index]) {
            $next = array_keys($a)[array_search($index,array_keys($a))+1];
            if ($index !== $max_index && !is_null($next)) {
                return mult_usort_callback($a, $b, $max_index, $next);
            } else {
                return 0;
            }
        }
        return $a[$index] > $b[$index] ? 1 : -1;
    }

    /* This part have been improved as we shouldn't use create_function()
       This function is now usable in PHP 7.2 */
    usort($arr, function ($a, $b) use ($max_index, $index) {
        return mult_usort_callback($a, $b, $max_index, $index);
    });
}

用法和輸出:

mult_usort_assoc($data, 'Site');
echo '<pre>' . print_r($data, true) . '</pre>';

此答案中使用的函數:

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM