如何在 PHP 中使这个平面数组在没有父 ID 的情况下分层?

How do I make this flat array hierarchical in PHP without parent IDs?

我有一个平面数组结构 ($rows),其中包含一个列数组 ($groupByCols),我想按以下方式对数据进行分组:

$groupByCols = ['a', 'b'];
$rows = [
    [
        'a' => 1,
        'b' => 10,
        'c' => 100
    ],
    [
        'a' => 1,
        'b' => 20,
        'c' => 200
    ],
    [
        'a' => 1,
        'b' => 20,
        'c' => 300
    ],
    [
        'a' => 1,
        'b' => 30,
        'c' => 400
    ],
    [
        'a' => 2,
        'b' => 40,
        'c' => 500
    ],
    [
        'a' => 2,
        'b' => 50,
        'c' => 600
    ],
    [
        'a' => 3,
        'b' => 60,
        'c' => 700
    ]
];

通过遍历 $rows 变量并按顺序引用每个 $groupByCols 值,我想获得以下分层数组:

$groupedRows = [
    [
        [
            [
                'a' => 1,
                'b' => 10,
                'c' => 100
            ]
        ],
        [
            [
                'a' => 1,
                'b' => 20,
                'c' => 200
            ],
            [
                'a' => 1,
                'b' => 20,
                'c' => 300
            ]
        ],
        [
            [
                'a' => 1,
                'b' => 30,
                'c' => 400
            ]
        ]
    ],
    [
        [
            [
                'a' => 2,
                'b' => 40,
                'c' => 500
            ]
        ],
        [
            [
                'a' => 2,
                'b' => 50,
                'c' => 600
            ]
        ]
    ],
    [
        [
            [
                'a' => 3,
                'b' => 60,
                'c' => 700
            ]
        ]
    ]
];

我 99% 确定我需要为此使用递归,但是在尝试了大约 10 种不同的方法(none 其中有效)之后,我不知道如何得到我想要的.

通常情况下,我会分享我到目前为止编写的代码,但在考虑了几天却一无所获之后,我真的没有太多可展示的东西。

我想我只需要一些关于如何(假设)递归地使用 $groupByCols$rows 变量来获取 $groupedRows 数组的一般指导。如有任何帮助,我们将不胜感激。

另请注意,以上数据仅供演示之用,非常简单。真实数据可能无限长、更复杂,我可能需要使用 $groupByCols 降低 5-6 个级别,具体取决于所需内容的性质。

谢谢。

这个函数会做你想做的。它遍历数组,按 $columns 中第一个值索引的值分组。如果 $columns 数组中还有剩余的列,它会按这些列递归分组。为了避免使用奇数编号的键,它调用 array_values 将结果重新索引为从 0 开始的数字键。

function group_by($array, $columns) {
    $new_arr = array();
    $column = array_shift($columns);
    foreach ($array as $arr) {
        $new_arr[$arr[$column]][] = $arr;
    }
    if (count($columns)) {
        foreach ($new_arr as &$arr) {
            $arr = group_by($arr, $columns);
        }
    }
    return array_values($new_arr);
}
print_r(group_by($rows, $groupByCols));

输出如你所愿,但不要用长打印来混淆答案,只需查看 3v4l.org 上的演示。