You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否将数据库返回的扁平数组转换为带动态键的多维数组?求实现方向指引

当然可行!这种多层分组嵌套的需求其实挺常见的,递归或者迭代的方式都能搞定,我给你拆解下具体的实现思路和步骤:

实现思路指引

核心逻辑:按分组键层级逐步构建树形结构

我们的目标是把扁平化的数据库返回数据,按照给定的分组键数组(比如["sm__state_name__", "om__order_date__year", ...])一层一层嵌套成你要的树形结构,每一层都要维护key、子节点items、当前层级的count和summary。

1. 初始化根容器

首先创建一个根容器来存放最终的data数组,同时准备好统计总数量的变量totalCount。

2. 遍历每条原始数据

对于每一条数据库返回的记录,我们需要沿着分组键的层级,一步步找到对应的节点:

  • 从根节点的data开始,依次使用当前分组键的值(比如第一条记录的Luanda、2017、3、8)作为key,检查当前层级的items里是否已经存在这个key的节点。
  • 如果不存在,就创建一个新的节点,包含key、空的items(最后一层设为null)、初始的count和summary。
  • 如果已经存在,就更新该节点的count(累加当前记录的count1)和summary(累加当前记录的sum1)。

3. 递归/迭代处理层级嵌套

这里推荐递归实现,因为分组键的数量不固定,递归可以灵活适配任意层级的分组:

  • 写一个递归函数,参数包括当前处理的分组键索引、当前层级的父节点、当前记录的数据。
  • 当处理到最后一个分组键时,直接创建叶子节点(items: null),并设置对应的count和summary。
  • 当不是最后一层时,找到或创建当前键对应的子节点,然后递归处理下一个分组键。

4. 计算各层级的汇总值

每一层的summary和count需要是其子节点的累加值,你可以在创建节点的时候实时累加父节点的数值(效率更高),也可以在构建完所有叶子节点后,递归从下往上汇总。


代码示例(PHP实现,适配你给出的数组格式)

function buildNestedTree(array $rawData, array $groupKeys): array {
    $root = ['data' => [], 'totalCount' => 0];
    
    foreach ($rawData as $item) {
        $currentLevel = &$root['data'];
        $currentCount = (int)$item['count1'];
        $currentSum = (float)$item['sum1'];
        
        // 遍历分组键,逐层构建节点
        for ($i = 0; $i < count($groupKeys); $i++) {
            $key = $item[$groupKeys[$i]];
            // 处理null值,避免分组异常
            if ($key === null) $key = 'Unknown';
            
            // 快速查找当前层级是否已有该key的节点
            $nodeExists = false;
            $nodeIndex = 0;
            foreach ($currentLevel as $idx => $node) {
                if ($node['key'] == $key) {
                    $nodeExists = true;
                    $nodeIndex = $idx;
                    break;
                }
            }
            
            if (!$nodeExists) {
                // 创建新节点
                $newNode = [
                    'key' => $key,
                    'items' => $i === count($groupKeys) - 1 ? null : [],
                    'count' => $i === count($groupKeys) - 1 ? $currentCount : 0,
                    'summary' => $i === count($groupKeys) - 1 ? [$currentSum] : [0.0]
                ];
                $currentLevel[] = $newNode;
                $nodeIndex = count($currentLevel) - 1;
            } else {
                // 更新叶子节点的数值
                if ($i === count($groupKeys) - 1) {
                    $currentLevel[$nodeIndex]['count'] += $currentCount;
                    $currentLevel[$nodeIndex]['summary'][0] += $currentSum;
                }
            }
            
            // 累加父节点的count和summary
            if ($i !== count($groupKeys) - 1) {
                $currentLevel[$nodeIndex]['count'] += $currentCount;
                $currentLevel[$nodeIndex]['summary'][0] += $currentSum;
            }
            
            // 移动到下一层级继续处理
            if ($i !== count($groupKeys) - 1) {
                $currentLevel = &$currentLevel[$nodeIndex]['items'];
            }
        }
        
        // 累加总数量
        $root['totalCount'] += $currentCount;
    }
    
    return $root;
}

// 使用示例
$rawData = [
    ['sum1' => '5645000', 'count1' => '4', 'sm__state_name__' => 'Luanda', 'om__order_date__year' => '2017', 'om__order_date__quarter' => '3', 'om__order_date__month' => '8'],
    ['sum1' => '213985939.8600001', 'count1' => '1606', 'sm__state_name__' => 'Luanda', 'om__order_date__year' => '2017', 'om__order_date__quarter' => '3', 'om__order_date__month' => '9'],
    // 其他记录可以继续添加
];
$groupKeys = ["sm__state_name__", "om__order_date__year", "om__order_date__quarter", "om__order_date__month"];

$result = buildNestedTree($rawData, $groupKeys);
echo json_encode($result, JSON_PRETTY_PRINT);

注意事项

  • 处理null值:如果分组键对应的值为null(比如示例中的某条记录sm__state_name__为null),可以统一替换为"Unknown"或者其他标识,避免出现分组异常。
  • 数值类型转换:数据库返回的sum1和count1通常是字符串,需要转换成对应的数值类型(float/int)再进行累加,否则会出现字符串拼接的错误。
  • 性能优化:如果数据量很大,遍历查找节点的方式效率较低,可以改用哈希表(比如用key作为数组的键)来快速定位节点,减少循环次数。

内容的提问来源于stack exchange,提问作者Vivek Makwana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:51:33