针对大型数据集按数组将分组优化为嵌套结构

时间:2019-05-05 14:25:44

标签: php arrays grouping

给出了带有字段(状态,类型等)的“平面”数组,这些字段可以是动态的(或多或少的键/值对),例如:

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

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

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

如果没有子代,则“数据”键应具有所有“原始”数据;如果有子代,则应将字段和值分组,如演示和此图像中的children/data

结果数据集应如下:

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

1 个答案:

答案 0 :(得分:2)

很遗憾,您没有解释这将用于什么目的,但这是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))

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

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