简体   繁体   English

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

[英]Combine Two Multidimensional Arrays in PHP With The Same ID

I want to add values from one array to another that are both potentially multidimensional when they have the same ID. 我想将值从一个数组添加到另一个数组,这些值在具有相同ID时都可能是多维的。 Hard to explain so I added example. 很难解释,所以我添加了示例。

arr1 => new structure, without full data arr1 =>新结构,没有完整数据

arr2 => old structure, with full data arr2 =>旧结构,包含完整数据

Examples if you'd like to help out: 如果您想帮忙的例子:

// 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"
}]

I tried this: 我尝试了这个:

    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;
    }

to combine them, but I can't figure out how to handle the nesting correctly. 合并它们,但是我不知道如何正确处理嵌套。 I have tried a lot of other things as well like using array_merge_recursive() but it doesn't work because I want to merge based on ID value. 我尝试了很多其他事情,例如使用array_merge_recursive(),但是它不起作用,因为我想基于ID值进行合并。 Any help on getting me on track would be awesome thanks. 非常感谢您帮助我步入正轨。

Current output for example: 当前输出例如:

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

Desired output for 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"
}]

Edit: How about this? 编辑:怎么样?

$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 is updated with the final result. $ array1更新为最终结果。

Here is an example with the data from your unedited post: http://phpio.net/s/7z09 这是未编辑帖子中数据的示例: http : //phpio.net/s/7z09

EDIT - I think I understand the problem now 编辑-我想我现在已经明白问题了

From the example you gave, I realised the problem - your old array has all the data, but not the parent-child relationships, so you want to populate the new array (with the correct relationships) with the data form the old array. 从您给出的示例中,我意识到了问题-您的旧数组具有所有数据,但没有父子关系,因此您想用旧数组中的数据填充新数组(具有正确的关系)。 The problem here is that the merge function would have to fetch data from an arbitrary generation in the old array to populate the new array. 这里的问题是合并函数必须从旧数组中的任意一代中获取数据才能填充新数组。 This could mean a lot of looping. 这可能意味着很多循环。

So I think the solution is first to loop through the old data and flatten it - just have an associative array where the key is the "id" value. 因此,我认为解决方案是首先遍历旧数据并将其展平-只是有一个关联数组,其键为“ id”值。 Then go through the new array and populate it from the flattened, "lookup" array. 然后遍历新数组,并从展平的“查找”数组中填充它。 Does that make sense? 那有意义吗? In any case, you'd have two functions: 无论如何,您将具有两个功能:

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

Then you populate the new array: 然后填充新数组:

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);

And $newArr should be what you're looking for $ newArr应该是您想要的

OLD USELESS STUFF FROM BEFORE: 以前的旧无用物品:

This part of your code is weird to me: 您的这段代码对我来说很奇怪:

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

Obviously I may be completely confused, but don't you just need to put this? 显然,我可能会完全困惑,但是您是否只需要输入这个?

if (isset($value2['children'])) $arr1[$key]['children'] = array_merge($arr1[$key]['children'], $value2['children']);

EDIT: I added array_merge because I saw that the 'children' array in the incomplete version could also need merging. 编辑:我添加了array_merge,因为我看到不完整版本中的“儿童”数组也可能需要合并。

EDIT 2: now I've noticed that children can have further children (makes sense, I guess), which is why you had the correct idea of using the function recursively. 编辑2:现在我注意到孩子可以再生孩子了(我想这很有意义),这就是为什么您有递归使用函数的正确想法的原因。 You just seem to have passed in the wrong arrays - you want to pass in $arr1[$key]['children'] (as the incomplete array) and $value2['children'] (as the complete array) 您似乎只是传入了错误的数组-您想传入$ 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM