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

Tutti i miei array sono alberi, un nodo può appartenere solo a un genitore. Voglio unire list1 con list2 e ottenere il resultList.ho provato in molti modi, callback ricorsivo, ricerca stringa & replace e così via, ma non riuscivo ancora a capirlo.come unire le matrici dimensionali

risposta

0

Il seguente codice unire tutti i livelli dei due array di alberi, non solo sul livello più alto:

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

vedere il codice in diretta su JSBin: http://jsbin.com/wikaricita/3/edit?js,output

Si noti che questo algoritmo ha una complessità di O (n^2), il che significa che non si ridimensionerà molto bene. Se gli alberi diventano molto grandi o le prestazioni sono un problema critico, probabilmente vorrai esaminare altri modi per risolvere questo problema.

+0

la lista3 è il risultato atteso. – Aflext

+0

I tuoi alberi array? Oppure un elemento può avere più genitori? Se si suppone che sia un albero, come si desidera gestire le definizioni in conflitto tra i due array che si desidera unire? – Timo

+0

Sì, i due array sono alberi. Quello che voglio fare è unire un nuovo array tree dal server a un array tree esistente nella memoria DOM come "aggiorna l'albero visualizzato". – Aflext

2

Se ho capito bene, lo vuoi compatto da 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; 
} 

L'array assomiglia var arr = [list1, list2]; Nella funzione creare un matrice e un oggetto. L'oggetto ottiene un id e un array. L'id è sempre lo stesso, quindi lo prendiamo dal primo array. Passare attraverso la matrice e spingere tutti gli oggetti arr[i][0].children[0]. Dopo il ciclo, premi obj nell'array. Restituisce la matrice dei risultati.

Demo

+0

Questo, tuttavia, non unisce l'albero completo in modo ricorsivo. Si fonde solo al primo livello, tutto ciò che viene dopo viene appena copiato. – Timo

Problemi correlati