如何在 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 上的演示。
我有一个平面数组结构 ($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 上的演示。