提问人:Chris C 提问时间:11/2/2023 最后编辑:mickmackusaChris C 更新时间:11/11/2023 访问量:71
按共享子数组值对多维数组中的数据集进行分组,并将累积值推送到组的列中
Group data sets in a multidimensional array by a shared subarray value and push accumulated values into a column of the group
问:
我正在使用 PHP,我有以下数组,并且一直在尝试弄清楚如何以以下方式将其扁平化。这是一个使用 json_decode 从 JSON 创建的数组,最终结果将是另一个 JSON 文件。
因此,无论我们在哪里有一个唯一的名称,在父数组的每个元素中,和 将始终相同。我需要一种方法来基本上“折叠”数组并组合数组,同时向操作数组添加新元素。patternType
type
当前数据结构。
[
'abc' => [
[
'foo' => '*',
'action' => 'Read',
'resource' => [
'name' => 'name_1',
'patternType' => 'fixed',
'type' => 'partition',
],
],
[
'foo' => '*',
'action' => 'Write',
'resource' => [
'name' => 'name_1',
'patternType' => 'fixed',
'type' => 'partition',
],
],
[
'foo' => '*',
'action' => 'Read',
'resource' => [
'name' => 'name_2',
'patternType' => 'fixed',
'type' => 'partition',
],
],
[
'foo' => '*',
'action' => 'Alter',
'resource' => [
'name' => 'name_2',
'patternType' => 'fixed',
'type' => 'partition',
],
],
],
];
所需的数据结构
Array
(
[abc] => Array
[0] => Array
(
[foo] => *
[action] => Array
(
[0] => Read
[1] => Write
)
[resource] => Array
(
[name] => name_1
[patternType] => fixed
[type] => partition
)
)
[1] => Array
(
[foo] => *
[action] => Array
(
[0] => Read
[1] => Alter
)
[resource] => Array
(
[name] => name_2
[patternType] => fixed
[type] => partition
)
)
)
我尝试了各种功能,如array_merges、array_merge_recursive等......我还尝试遍历数组,并创建一个辅助数组并在那里正确创建数据结构,但我总是遇到一个问题,即在这种情况下如何引用父数组,b/c 子数组的顺序总是不同的。
答:
这是适合您的解决方案
<?php
$array = [
"abc" => [
[
"foo" => "*",
"action" => "Read",
"resource" => [
"name" => "name_1",
"patternType" => "fixed",
"type" => "partition"
]
],
[
"foo" => "*",
"action" => "Write",
"resource" => [
"name" => "name_1",
"patternType" => "fixed",
"type" => "partition"
]
],
[
"foo" => "*",
"action" => "Read",
"resource" => [
"name" => "name_2",
"patternType" => "fixed",
"type" => "partition"
]
],
[
"foo" => "*",
"action" => "Alter",
"resource" => [
"name" => "name_2",
"patternType" => "fixed",
"type" => "partition"
]
],
]
];
$grouparr = [];
$tempVal;
$action;
foreach ($array['abc'] as $key => $val) {
if (isset($tempVal['resource']['name']) && ($val['resource']['name'] == $tempVal['resource']['name'])){
$grouparr[$key] = $val;
$actions = [$action];
array_push($actions, $grouparr[$key]['action']);
$grouparr[$key]['action'] = $actions;
} else {
$action = $val['action'];
$tempVal = $val;
}
}
print_r(array_values($grouparr));
?>
评论
@
为了实现所需的数据结构,您可以遍历原始数组并使用临时关联数组按“name”字段对元素进行分组。然后,您可以从此临时数组创建所需的结构。下面是一个PHP代码示例:
$outputArray = [];
foreach ($inputArray as $key => $items) {
$tempArray = [];
foreach ($items as $item) {
$name = $item['resource']['name'];
if (!isset($tempArray[$name])) {
$tempArray[$name] = [
'foo' => $item['foo'],
'action' => [],
'resource' => $item['resource'],
];
}
$tempArray[$name]['action'][] = $item['action'];
}
$outputArray[$key] = array_values($tempArray);
}
echo "<pre>";
print_r($outputArray);
这将在 中为您提供所需的数据结构。$outputArray
通过在结果数组中推送引用变量,可以避免清除不需要的键。这是一种更直接的方法。array_values()
我认为“资源名称”是识别数据集唯一性的可靠方法。通过此标识符声明引用变量。
如果以前没有遇到过标识符,请将该值强制转换为孤元素数组,定义引用变量的数据,然后推入结果数组。如果之前遇到过标识符,只需将新值推送到引用的子数组中即可。action
action
action
代码:(演示)
$result = [];
foreach ($array as $key => $sets) {
foreach ($sets as $set) {
$id = $set['resource']['name'];
if (!isset($ref[$id])) {
$set['action'] = (array) $set['action'];
$ref[$id] = $set;
$result[$key][] = &$ref[$id];
} else {
$ref[$id]['action'][] = $set['action'];
}
}
}
var_export($result);
或者,如果您只想改变输入数组而不生成新数组,请调整引用以指向给定值的第一个遇到集合的子数组。action
name
代码:(演示)
foreach ($array as $key => &$sets) {
foreach ($sets as $i => &$set) {
$id = $set['resource']['name'];
if (!isset($ref[$id])) {
$set['action'] = (array) $set['action'];
$ref[$id] = &$set['action'];
} else {
$ref[$id][] = $set['action'];
unset($array[$key][$i]);
}
}
}
var_export($array);
评论