使用相同的ID在PHP中组合两个多维数组

时间:2018-05-20 17:27:13

标签: php arrays

我想将一个数组中的值添加到另一个数组中,当它们具有相同的ID时,它们都可能是多维的。很难解释所以我添加了例子。

arr1 =>新结构,没有完整数据

arr2 =>旧结构,包含完整数据

如果你想提供帮助的例子:

// arr1 (the correct structure/order, without the full data)
[{
    "id": "24",
    "children": [{
        "id": "21",
        "children": [{
            "id": "15"
        }]
    }]
}]



// arr2 (full data, not in any specific order, may be nested)
[{
    "id": "24",
    "name": " x",
    "time": "0",
    "status": "0"
}, {
    "id": "21",
    "children": [{
        "id": "15",
        "name": "x",
        "time": "0",
        "status": "0"
    }],
    "name": "x",
    "time": "0",
    "status": "0"
}]


// arr3 (desired output for this example)
[{
    "id": "24",
    "children": [{
        "id": "21",
        "children": [{
            "id": "15",
            "name": "x",
            "time": "0",
            "status": "0"
        }],
        "name": "x",
        "time": "0",
        "status": "0"
    }],
    "name": " x",
    "time": "0",
    "status": "0"
}]

我试过了:

    function merge($arr1, $arr2) {
        foreach($arr1 as $key => $value){
            foreach($arr2 as $value2) {
                if($value['id'] === $value2['id']){
                    $arr1[$key]['name'] = $value2['name'];
                    $arr1[$key]['time'] = $value2['time'];
                    $arr1[$key]['status'] = $value2['status'];
                    if (is_array($value)) {
                        $arr1[$key]['children'] = merge($arr1, $arr2);
                    }
                }

            }
        }
        return $arr1;
    }

将它们组合起来,但我无法弄清楚如何正确处理嵌套。我已经尝试了很多其他的东西,比如使用array_merge_recursive(),但它不起作用,因为我想基于ID值进行合并。让我走上正轨的任何帮助都会非常棒,谢谢。

当前输出例如:

[{
    "id": "24",
    "children": [{
        "id": "21",
        "children": [{
            "id": "15"
        }]
    }],
    "name": " x",
    "time": "0",
    "status": "0"
}]

所需的输出例如:

[{
    "id": "24",
    "children": [{
        "id": "21",
        "children": [{
            "id": "15",
            "name": "x",
            "time": "0",
            "status": "0"
        }],
        "name": "x",
        "time": "0",
        "status": "0"
    }],
    "name": " x",
    "time": "0",
    "status": "0"
}]

2 个答案:

答案 0 :(得分:2)

编辑:这个怎么样?

$detailsClean = [];

foreach($array2 as $item) {
    $detailsClean = removeDepth($item, $detailsClean);
}


foreach($array1 as $itemKey => $item) {
    $array1[$itemKey] = addDetails($item, $detailsClean);
}


function removeDepth($array, $result) {
    $id = $array['id'];
    if (!empty($array['children'])) {
        foreach($array['children'] as $child) {
            $result = removeDepth($child, $result);
        }
        unset($array['children']);
    }
    $result[$id] = $array;

    return $result;
}

function addDetails($array, $details) {
    $id = $array['id'];
    if (isset($details[$id])) {
        $array = array_merge($array, $details[$id]);
        if (!empty($array['children'])) {
            foreach($array['children'] as $childKey => $child) {
                $array['children'][$childKey] = addDetails($child, $details);
            }
        }
    }
    return $array;
}

$ array1使用最终结果进行更新。

以下是您未经编辑的帖子中的数据示例:http://phpio.net/s/7z09

答案 1 :(得分:1)

编辑 - 我想我现在明白了这个问题

从您给出的示例中,我意识到了问题 - 您的旧数组包含所有数据,但不包含父子关系,因此您希望使用旧数据填充新数组(具有正确的关系)阵列。这里的问题是合并函数必须从旧数组中的任意一代获取数据以填充新数组。这可能意味着很多循环。

所以我认为解决方案是首先遍历旧数据并将其展平 - 只需要一个关联数组,其中键是" id"值。然后浏览新的数组并从展平的"查找"中填充它。阵列。那有意义吗?无论如何,您有两个功能:

$lookUp = array();

//recursive function to flatten $arr2 into $lookUp array.
function indexOriginal($arr, &$lookUp) {
    foreach($arr as $value) {
        $lookUp[$value["id"]] = $value;
        if (isset($value['children'])) {
            unset($lookUp[$value["id"]]['children']);
            indexOriginal($value['children'], $lookUp);
        }
    }
}
indexOriginal($arr2, $lookUp);

然后填充新数组:

function fillInNew($arr, $lookUp) {
    $return = array();
    foreach($arr as $value) {
        $newEntry = $lookUp[$value["id"]];
        if (isset($value['children'])) $newEntry['children'] = fillInNew($value['children'], $lookUp);
        $return[] = $newEntry;
    }
    return $return;
}
$newArr = fillInNew($arr1, $lookUp);

$ newArr应该是你正在寻找的东西

来自以前的无用小吃:

这部分代码对我来说很奇怪:

if (is_array($value)) {
    $arr1[$key]['children'] = merge($arr1, $arr2);
}

显然我可能会感到很困惑,但是你不需要这么做吗?

if (isset($value2['children'])) $arr1[$key]['children'] = array_merge($arr1[$key]['children'], $value2['children']);
编辑:我添加了array_merge,因为我看到了孩子们的#39;不完整版本中的数组也可能需要合并。

编辑2:现在我注意到孩子们可以有更多的孩子(我猜是有道理的),这就是为什么你有正确的想法,递归使用这个功能。你似乎传入了错误的数组 - 你想传入$ arr1 [$ key] [' children'](作为不完整的数组)和$ value2 [' children' ](作为完整的数组)

function merge($arr1, $arr2) {
    foreach($arr1 as $key => $value){
        foreach($arr2 as $value2) {
            if($value['id'] === $value2['id']){
                $arr1[$key]['name'] = $value2['name'];
                $arr1[$key]['time'] = $value2['time'];
                $arr1[$key]['status'] = $value2['status'];
                if (isset($value2['children'])) $arr1[$key]['children'] = merge($arr1[$key]['children'], $value2['children']);
            }

        }
    }
    return $arr1;
}