通过共享子数组值将多维数组中的数据集分组,并将累积值推送到组的列中

问题描述 投票:0回答:3

我正在使用 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 arrays multidimensional-array grouping
3个回答
1
投票

要实现所需的数据结构,您可以循环原始数组并使用临时关联数组按 “name” 字段对元素进行分组。然后,您可以从此临时数组创建所需的结构。下面是执行此操作的 PHP 代码示例:

$inputArray = [
    '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',
            ],
        ],
    ],
];

$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


0
投票

这是适合您的解决方案

<?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 ($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));

?>


0
投票
通过将引用变量推送到结果数组中,可以避免使用

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);
    
© www.soinside.com 2019 - 2024. All rights reserved.