为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PHP
慕的地6264312 2021-05-06 18:26:54
给出了带有字段(状态,类型等)的“平面”数组,这些字段可以是动态的(或多或少的键/值对),例如:$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我将解决方案从(将php数组重新排列为嵌套的层次结构数组)改编而成,但是它很凌乱,并且占用大量内存和时间。是否可以针对大型数据集(10000个及更多“平面”数组记录)进行优化,提高性能并美化代码?这将用于计算每个组的小计(总和,计数,平均值等)。演示版
查看完整描述

1 回答

?
饮歌长啸

TA贡献1951条经验 获得超3个赞

遗憾的是您没有解释它的用途,但这是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))

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


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


查看完整回答
反对 回复 2021-05-28
  • 1 回答
  • 0 关注
  • 145 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信