PHP多维数组合并相同的键和值

迪尔西娜

我花了数小时试图找到这个问题的答案,但我一直在努力。我相当熟悉PHP和各种内置函数,并且可以构建一个复杂的foreach()循环来执行此操作,但是我认为我想问问是否有人对我的问题有更明智的解决方案。

我有以下带有三个“行”的简化示例数组(实际数组通常更大,更复杂,但问题是相同的)。

$rows[] = [
    "widget_id" => "widget1",
    "size" => "large",
    "item" => [
        "item_id" => "item1",
        "shape" => "circle",
        "paint" => [
            "paint_id" => "paint1",
            "colour" => "red",
        ]
    ]
];

# Exactly the same as above, except the "paint" child array is different
$rows[] = [
    "widget_id" => "widget1",
    "size" => "large",
    "item" => [
        "item_id" => "item1",
        "shape" => "circle",
        "paint" => [
            "paint_id" => "paint2",
            "colour" => "green",
        ]
    ]
];

# Same children ("item" and "paint") as the first row, but different parents ("widget_id" is different)
$rows[] = [
    "widget_id" => "widget2",
    "size" => "medium",
    "item" => [
        "item_id" => "item1",
        "shape" => "circle",
        "paint" => [
            "paint_id" => "paint1",
            "colour" => "red",
        ]
    ]
];

我想要得到的是以下输出:

[[
    "widget_id" => "widget1",
    "size" => "large",
    "item" => [
        "item_id" => "item1",
        "shape" => "circle",
        "paint" => [[
            "paint_id" => "paint1",
            "colour" => "red",
        ],[
            "paint_id" => "paint2",
            "colour" => "green",
        ]]
    ]
],[
    "widget_id" => "widget2",
    "size" => "medium",
    "item" => [
        "item_id" => "item1",
        "shape" => "circle",
        "paint" => [
            "paint_id" => "paint1",
            "colour" => "red",
        ]
    ]
]]

基本上,当两行共享相同的键和值时,请合并它们。当键相同但值不同时,请保留两个值并将它们放在键下的数字数组中(类似如何array_merge_recursive操作)。

挑战在于值本身可以是数组,并且级别数未知。是否有一种聪明而有效的方法来执行此操作,还是我必须诉诸繁重的工作foreach循环?

感谢您的浏览,希望有比我更聪明的人阅读本文!

艾姆德夫

我通过以下功能获得了预期的数组结构,希望其中的注释是明确的:

function complex_merge(array $arr): array
{
    // Grouped items
    $result = [];
    $iterationKey = 0;

    // Loop through every item
    while (($element = array_shift($arr)) !== null) {
        // Save scalar values as is
        $scalarValues = array_filter($element, 'is_scalar');

        // Save array values in an array
        $arrayValues = array_map(fn(array $arrVal) => [$arrVal], array_filter($element, 'is_array'));
        $arrayValuesKeys = array_keys($arrayValues);

        $result[$iterationKey] = array_merge($scalarValues, $arrayValues);

        // Compare with remaining items
        for ($i = 0; $i < count($arr); $i++) {
            $comparisonScalarValues = array_filter($arr[$i], 'is_scalar');

            // Scalar values are same, add the array values to the containing arrays
            if ($scalarValues === $comparisonScalarValues) {
                $comparisonArrayValues = array_filter($arr[$i], 'is_array');
                foreach ($arrayValuesKeys as $arrayKey) {
                    $result[$iterationKey][$arrayKey][] = $comparisonArrayValues[$arrayKey];
                }

                // Remove matching item
                array_splice($arr, $i, 1);
                $i--;
            }
        }

        // Merge array values
        foreach ($arrayValuesKeys as $arrayKey) {
            $result[$iterationKey][$arrayKey] = complex_merge($result[$iterationKey][$arrayKey]);

            // array key contains a single item, extract it
            if (count($result[$iterationKey][$arrayKey]) === 1) {
                $result[$iterationKey][$arrayKey] = $result[$iterationKey][$arrayKey][0];
            }
        }

        // Increment result key
        $iterationKey++;
    }
    return $result;
}

只需传递$rows给函数,即可快速检查值:

echo '<pre>' . print_r(complex_merge($rows), true) . '</pre>';

/*
Displays:
Array
(
    [0] => Array
        (
            [widget_id] => widget1
            [size] => large
            [item] => Array
                (
                    [item_id] => item1
                    [shape] => circle
                    [paint] => Array
                        (
                            [0] => Array
                                (
                                    [paint_id] => paint1
                                    [colour] => red
                                )

                            [1] => Array
                                (
                                    [paint_id] => paint2
                                    [colour] => green
                                )

                        )

                )

        )

    [1] => Array
        (
            [widget_id] => widget2
            [size] => medium
            [item] => Array
                (
                    [item_id] => item1
                    [shape] => circle
                    [paint] => Array
                        (
                            [paint_id] => paint1
                            [colour] => red
                        )

                )

        )

)
*/

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

基于键和值的PHP数组合并

来自分类Dev

PHP多维数组合并

来自分类Dev

转换多维PHP数组的键和值

来自分类Dev

php多维数组的打印键和值

来自分类Dev

PHP多维数组键组合/组合

来自分类Dev

在多维数组中合并相同的键

来自分类Dev

使用相同键的数组合并

来自分类Dev

PHP:多维数组合并递归

来自分类Dev

使用php进行多维数组合并

来自分类Dev

PHP多维数组合并问题

来自分类Dev

如何根据相同的键组合PHP循环中的数组值

来自分类Dev

PHP数组与相同的键合并

来自分类Dev

通过共享键合并多维数组值

来自分类Dev

多维数组合并

来自分类Dev

将数组合并为键值相同的多维数组

来自分类Dev

PHP-基于键合并多维数组

来自分类Dev

遍历php多维数组的每个键和值

来自分类Dev

修改多维数组PHP中的键和值

来自分类Dev

从多维数组PHP中删除Int键和值

来自分类Dev

如何在新数组中获取Php多维数组相同键的相同值的相关总数?

来自分类Dev

从多维数组合并数组

来自分类Dev

内键上的 PHP 数组合并

来自分类Dev

合并php数组合并而不删除数组键

来自分类Dev

合并PHP数组以创建命名键和唯一值

来自分类Dev

如何将键数组和值数组合并到一个对象中?

来自分类Dev

如何合并保留唯一键并用逗号分隔其他值的PHP多维数组

来自分类Dev

PHP 删除重复键并将值合并到多维数组中

来自分类Dev

PHP:合并和排序两个具有相同值的多维数组

来自分类Dev

PHP多维数组:检索给定键的值