【问题标题】:how to merge dimensional arrays如何合并维度数组
【发布时间】:2015-07-29 04:18:25
【问题描述】:
var list1 = [
    {
        id: 'node1',
        children: [
            {
                id: 'node11',
                children: []
            }
        ]
    }
];

var list2 = [
    {
        id: 'node1',
        children: [
            {
                id: 'node13',
                children: []
            }
        ]
    }
];
var resultList = [
    {
        id: 'node1',
        children: [
            {
                id: 'node11',
                children: []
            }, {
                id: 'node13',
                children: []
            }
        ]
    }
];

我所有的数组都是树,一个节点只能属于一个父节点。 我想把list1和list2合并,得到resultList。我尝试了很多方法,递归回调,字符串搜索&替换等等,但还是想不通。

【问题讨论】:

    标签: javascript arrays json multidimensional-array merge


    【解决方案1】:

    如果我理解正确,您希望它按 id 压缩。

    function getCompactById(arr) { // must have the same id
        var res = [];
        var obj = {};
        obj.id = arr[0][0].id;
        obj.children = [];
        for(var i = 0; i < arr.length; i += 1) {
            obj.children.push(arr[i][0].children[0]);
        }
        res.push(obj);
        return res;
    }
    

    数组看起来像 var arr = [list1, list2]; 在函数 create 中,有一个 array 和一个 object。该对象获得一个 id 和一个数组。 id 总是相同的,所以我们从第一个数组中获取它。遍历数组并推送所有对象arr[i][0].children[0]。循环后将 obj 推入数组。返回结果数组。

    Demo

    【讨论】:

    • 然而,这不会递归地合并整个树。它只在第一级合并,之后的所有内容都会被复制。
    【解决方案2】:

    以下代码将合并两个树数组的所有级别,而不仅仅是最上层:

    var list1 = ...
    var list2 = ...
    
    var addNode = function(nodeId, array) {
      array.push({id: nodeId, children: []});
    };
    
    var placeNodeInTree = function(nodeId, parent, treeList) {
      return treeList.some(function(currentNode){
    
        // If currentNode has the same id as the node we want to insert, good! Required for root nodes.
        if(currentNode.id === nodeId) {
          return true;  
        }
    
        // Is currentNode the parent of the node we want to insert?
        if(currentNode.id === parent) {
    
          // If the element does not exist as child of currentNode, create it
          if(!currentNode.children.some(function(currentChild) {
            return currentChild.id === nodeId;
          })) addNode(nodeId, currentNode.children);
    
          return true;
        } else {
    
          // Continue looking further down the tree
          return placeNodeInTree(nodeId, parent, currentNode.children);
        }
      });
    };
    
    var mergeInto = function(tree, mergeTarget, parentId) {
      parentId = parentId || undefined;
      tree.forEach(function(node) {
    
        // If parent has not been found, placeNodeInTree() returns false --> insert as root element
        if(!placeNodeInTree(node.id, parentId, mergeTarget)){
          list1.push({id: node.id, children:[]});
        }
    
        mergeInto(node.children, mergeTarget, node.id);
    
      });
    };
    
    mergeInto(list2, list1);
    
    document.write('<pre>');
    document.write(JSON.stringify(list1, null, 4));
    document.write('</pre>');
    

    在 JSBin 上实时查看代码:http://jsbin.com/wikaricita/3/edit?js,output

    请注意,这个算法的复杂度为 O(n^2),这意味着它不会很好地扩展。如果树变得非常大或性能是一个关键问题,您可能需要研究解决此问题的其他方法。

    【讨论】:

    • list3 是预期的结果。
    • 你的数组是树吗?或者一个元素可以有多个父元素?如果它应该是一棵树,你想如何处理要合并的两个数组之间的冲突定义?
    • 是的,这两个数组是树。我想做的是将服务器中的新树数组合并到 DOM 内存中的现有树数组,例如“更新显示的树”。
    猜你喜欢
    • 2021-12-27
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    相关资源
    最近更新 更多