The following code combines all levels of two arrays of trees, and not just at the highest level:
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>');
Watch the code live on JSBin: http://jsbin.com/wikaricita/3/edit?js,output
Note that this algorithm has O (n ^ 2) complexity, which means that it will not scale very well. If the trees are getting very large or performance is a critical issue, you probably want to explore other ways to solve this problem.
Timo source share