2015-05-17 12 views
6
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: [] 
      } 
     ] 
    } 
]; 

Wszystkie moje tablice są drzewami, jeden węzeł może należeć tylko do jednego rodzica. Chcę scalić list1 z list2 i uzyskać resultList. Próbowałem na wiele sposobów, rekursywne wywołanie zwrotne, wyszukiwanie ciągów znaków & zamień i tak dalej, ale nadal nie mogłem tego rozgryźć.jak łączyć tablice wymiarowe

Odpowiedz

0

Poniższy kod połączy wszystkie poziomy dwóch tablicach drzew, a nie tylko na górnej większości poziomie:

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

zobaczyć kod żyć JSBin: http://jsbin.com/wikaricita/3/edit?js,output

pamiętać, że ten algorytm złożoność O (n^2), co oznacza, że ​​nie będzie się naprawdę dobrze skalować. Jeśli drzewa stają się bardzo duże, a wydajność to krytyczny problem, prawdopodobnie warto przyjrzeć się innym sposobom rozwiązania tego problemu.

+0

the list3 jest oczekiwanym rezultatem. – Aflext

+0

Czy twoje drzewa tablicowe? A może element ma wielu rodziców? Jeśli ma to być drzewo, jak chcesz obsługiwać sprzeczne definicje między dwoma tablicami, które chcesz scalić? – Timo

+0

Tak, dwie tablice są drzewami. Chcę utworzyć nową tablicę drzewiastą z serwera do istniejącej tablicy drzew w pamięci DOM, np. "Zaktualizuj wyświetlane drzewo". – Aflext

2

Jeśli dobrze Cię rozumiem, chcesz, aby był zwarty przez 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; 
} 

Tablica wygląda var arr = [list1, list2]; W funkcji tworzyćtablicę oraz przedmiotu. Obiekt otrzymuje identyfikator i tablicę. Identyfikator jest zawsze taki sam, więc bierzemy go z pierwszej tablicy. Przejdź przez tablicę i przesuń wszystkie obiekty arr[i][0].children[0]. Po pętli popchnij obiekt w tablicy. Zwróć tablicę wyników.

Demo

+0

Nie łączy to jednak całego drzewa rekursywnie. Łączy się tylko na pierwszym poziomie, po czym wszystko zostaje skopiowane. – Timo