【问题标题】:Optimize group by array into nested structure for large data sets将按数组优化为大型数据集的嵌套结构
【发布时间】:2019-09-23 08:50:06
【问题描述】:

给定的“平面”数组包含可能是动态的(或多或少的键/值对)的字段(状态、类型等),例如:

$data = array(
    array(
        "status" => "new",
        "type" => "type1",
        "source" => "source1",
        "other" => "other1",
        "count" => "1",
    ),
    ...

目标是通过不同数量的分组字段来“分组”多维/嵌套数组。例如,如果需要按4个字段分组:

$groups = array("status", "type", "source", "other");

如果没有子项,则“数据”键应包含所有“原始”数据,如果有子项,则将字段和值分组,如演示中和此图像中的

结果数据集应该如下:

Array
(
    [0] => Array
        (
            [fieldName] => status
            [value] => new
            [children] => Array
                (
                    [0] => Array
                        (
                            [fieldName] => type
                            [value] => type1
                            [children] => Array
                                (
                                    [0] => Array
                                        (
                                            [fieldName] => source
                                            [value] => source1
                                            [children] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [fieldName] => other
                                                            [value] => other1
                                                            [data] => Array
                                                                (
                                                                    [0] => Array
                                                                        (
                                                                            [status] => new
                                                                            [type] => type1
                                                                            [source] => source1
                                                                            [other] => other1
                                                                            [count] => 1
                                                                        )

我从 (rearrange a php array into a nested hierarchical array) 改编了解决方案,但它非常混乱,而且需要大量的内存和时间。能否针对大型数据集(10000 条及更多“平面”数组记录)进行优化,提高性能并美化代码?

这将用于计算每个组的小计(总和、计数、平均值等)。

Demo

【问题讨论】:

    标签: php arrays grouping


    【解决方案1】:

    很遗憾,您没有解释它的用途,但这是 Stack Overflow 问题的常见问题。问题的本质往往是缺失的,所以它变成了一个抽象的练习。

    例如,我看不出以这种特定方式重新排列数组的意义。我认为生成的数组可以更有效地使用数组键。还有很多重复的信息。

    但这就是我们得到的,所以我没有进一步抱怨,这是我想出的代码:

    function rearrangeItems($flatItems, $groups)
    {
        $groupedItems = [];
        $groupName    = array_shift($groups);
        $groupValues  = array_unique(array_column($flatItems, $groupName));
        foreach ($groupValues as $groupValue) {
            $children = [];
            foreach ($flatItems as $flatItem) {
                if ($flatItem[$groupName] == $groupValue) {
                    $children[] = $flatItem;
                }    
            }    
            if (count($groups) > 0) {
                $children = rearrange($children, $groups);
                $groupKey = "children";
            }
            else {
                $groupKey = "data";
            }
            $groupedItems[] = ["fieldName" => $groupName, 
                               "value"     => $groupValue,
                               $groupKey   => $children];
        }    
        return $groupedItems;
    }
    

    是的,这就是我们所需要的。它产生相同的输出。

    这个函数是递归的,它会进行一层分组,然后将结果传递给下一层,直到没有更多的层。复杂的位是:

    array_unique(array_column($flatItems, $groupName))
    

    它返回当前分组级别的所有不同值。

    这不是绝对最有效的算法,但可以理解。如果我试图让它更高效,可读性可能会受到影响,这绝不是一件好事。

    【讨论】:

    • 感谢您的回答。这用于计算每个组/子组的小计。有一个通知 - 如果没有“孩子”,那么组应该有关键的“数据”,其中包含我在 PHP 小提琴中显示的记录值的原始数据。
    • 啊,我没发现。因此,如果有多个子记录,则键为“children”,如果有一条记录,则键为“data”。这没有任何意义,但不是问题。我将更改我的代码。
    • 其实是有道理的,因为“data”包含了详细数据或者“原始”数据,而“children”的意思是它是组,有子组。
    • 差不多 :) 对不起,我想我没有正确解释。我会以另一种方式尝试。如果所有组都“分组”,那么它应该有关键的“孩子”,但最后一个组应该有关键的“数据”(最后一个嵌套级别)。有点不同。
    • 哦,是的,我明白了。呃...再次更改它。
    猜你喜欢
    • 1970-01-01
    • 2013-06-04
    • 2019-11-21
    • 2012-11-27
    • 2022-06-10
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多