如何在PHP 5.4版中对多维数组进行排序-带键? [英] How to sort multidimensional array in PHP version 5.4 - with keys?

查看:108
本文介绍了如何在PHP 5.4版中对多维数组进行排序-带键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我问了一个此处非常相似的问题并收到了很好的答案.

I asked a very similar question here and received an excellent answer.

但是后来我不得不对数组数据进行一次更改,它破坏了排序算法,我不知道为什么.

But then I had to make one change to my array data, it broke the sort algorithm, and I don't know why.

在上一个问题中,我的数组如下所示:

In the previous question my array looked like this:

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中的以下排序算法对它进行了出色的排序:

And applying the following sort algorithm from AymDev sorted it brilliantly:

$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 . ');'));
}

这对我的多维数组进行了排序,到目前为止,一切都很完美.

This sorts my multidim array and so far everything is perfect.

但是后来我改变了我的数组结构:

But then I made a change to my array structure thusly:

[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] => 
    )

观察到我将键从索引器更改为列名.这对我处理后续逻辑非常有帮助.除了更改数据/密钥外,我还尝试更改日期对象化:

Observe that I changed the keys from indexers to column names. This is hugely helpful to me in processing later logic. Along with this data/key change, I attempted to change the date objectification thusly:

$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不同.在以前的数组结构(使用索引键而不是命名键)中,排序是正确的.

That did appear to work from the standpoint of converting the string dates into date objects. But it broke the sorting. You can see evidence of the broken sort by looking at the 3 elements of the new array. Observe that array segments 151 and 153 should be consecutive because Game, Date, and Site are identical. 152 does not have identical values to 151 and 152. Game and Date are the same, but Site is different. In the previous array structure (using index keys instead of named keys) the sort was correct.

我怀疑我需要对SortSheet()函数进行某种更改,但我不知道它是什么.

I suspect that I need to make some sort of change to the SortSheet() function, but I can't figure out what it is.

重要说明:键名序列将始终相同.换句话说,按键序列始终是游戏",日期",站点"等.因此,该序列始终可以被计数.

有什么想法吗?

推荐答案

使用先前按数字顺序排列的数组的快速修复方法可能是:

An quick fix, using the previous numerically ordered array, could have been:

// 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);

但是,让我们更新我的上一个功能:

But let's update my previous function:

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>';


此答案中使用的功能:


Used functions in this answer:

这篇关于如何在PHP 5.4版中对多维数组进行排序-带键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆