代码之家  ›  专栏  ›  技术社区  ›  anon

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

  •  0
  • anon  · 技术社区  · 6 年前

    我想将一个数组中的值添加到另一个数组中,当它们具有相同的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 回复  |  直到 6 年前
        1
  •  2
  •   Thijn    6 年前

    编辑: 这个怎么样?

    $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

        2
  •  1
  •   Michael Beeson    6 年前

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

    从您给出的示例中,我意识到了这个问题——您的旧数组拥有所有数据,但没有父子关系,因此您希望用旧数组中的数据填充新数组(具有正确的关系)。这里的问题是合并函数必须从旧数组中任意生成的数据中提取数据来填充新数组。这可能意味着很多循环。

    所以我认为解决方案是首先遍历旧数据并将其变平——只需要有一个关联数组,其中键是“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']);
    

    编辑:我添加了数组合并,因为我看到不完整版本中的“子”数组也可能需要合并。

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