给出了带有字段(状态,类型等)的“平面”数组,这些字段可以是动态的(或多或少的键/值对),例如:
$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
(
[status] => new
[type] => type1
[source] => source1
[other] => other1
[count] => 1
)
我改编了(rearrange a php array into a nested hierarchical array)的解决方案,但是它很凌乱,并且需要大量的内存和时间。是否可以针对大型数据集(10000个和更多“平面”数组记录)进行优化,提高性能并美化代码?
这将用于计算每个组的小计(总和,计数,平均值等)。
答案 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))
它返回当前分组级别的所有不同值。
这不是绝对最有效的算法,但可以理解。如果我试图使其更高效,那么可读性可能会受到影响,这绝对不是一件好事。