2013-03-13 34 views
8

http://jsfiddle.net/eYgGK/JSON gerarchica dal piatto con ID genitore

Ho rubato questo script da un altro posto:

function convertToHierarchy() { 
var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" }, 
       { "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" }, 
       { "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" }, 
       { "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }]; 
     var nodeObjects = createStructure(arry); 
     for (var i = nodeObjects.length - 1; i >= 0; i--) { 
      var currentNode = nodeObjects[i]; 
      if (currentNode.value.Parent === "") { 
       continue; 
      } 
      var parent = getParent(currentNode, nodeObjects); 

      if (parent === null) { 
       continue; 
      } 

      parent.children.push(currentNode); 
      nodeObjects.splice(i, 1); 
     } 
     console.dir(nodeObjects); 
     return nodeObjects; 
    } 
    function createStructure(nodes) { 
     var objects = []; 

     for (var i = 0; i < nodes.length; i++) { 
      objects.push({ value: nodes[i], children: [] }); 
     } 

     return objects; 

    } 
    function getParent(child, nodes) { 
     var parent = null; 

     for (var i = 0; i < nodes.length; i++) { 
      if (nodes[i].value.Id === child.value.Parent) { 
       return nodes[i]; 
      } 
     } 

     return parent; 
    } 

Questo script produce:

[{ 
    "value": { 
     "Id": "1", 
     "Name": "abc", 
     "Parent": "", 
     "attr": "abc" 
    }, 
    "children": [{ 
     "value": { 
      "Id": "2", 
      "Name": "abc", 
      "Parent": "1", 
      "attr": "abc" 
     }, 
     "children": [{ 
      "value": { 
       "Id": "4", 
       "Name": "abc", 
       "Parent": "2", 
       "attr": "abc" 
      }, 
      "children": [] 
     }, { 
      "value": { 
       "Id": "3", 
       "Name": "abc", 
       "Parent": "2", 
       "attr": "abc" 
      }, 
      "children": [] 
     }] 
    }] 
}] 

Quello che sto cercando:

[{ 
    "Id": "1", 
    "Name": "abc", 
    "Parent": "", 
    "attr": "abc", 
    "children": [{ 

     "Id": "2", 
     "Name": "abc", 
     "Parent": "1", 
     "attr": "abc", 
     "children": [{ 

      "Id": "4", 
      "Name": "abc", 
      "Parent": "2", 
      "attr": "abc" 
     }, { 

      "Id": "3", 
      "Name": "abc", 
      "Parent": "2", 
      "attr": "abc" 

     }] 
    }] 
}] 

Ho bisogno di liberarmi del wrapper "value" principalmente e del nodo figlio vuoto secondariamente. So che posso scrivere uno script di pulizia, ma sarebbe meno delle migliori pratiche. Sarebbe bello se qualcuno sapesse come risolvere o suggerire uno script diverso!

Grazie

risposta

17

Provare qualcosa di simile

var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" }, 
       { "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" }, 
       { "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" }, 
       { "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }]; 

function convert(array){ 
    var map = {}; 
    for(var i = 0; i < array.length; i++){ 
     var obj = array[i]; 
     obj.items= []; 

     map[obj.Id] = obj; 

     var parent = obj.Parent || '-'; 
     if(!map[parent]){ 
      map[parent] = { 
       items: [] 
      }; 
     } 
     map[parent].items.push(obj); 
    } 

    return map['-'].items; 

} 

var r = convert(arry) 

Demo: Fiddle

Risultato

[{ 
    "Id" : "1", 
    "Name" : "abc", 
    "Parent" : "", 
    "attr" : "abc", 
    "children" : [{ 
       "Id" : "2", 
       "Name" : "abc", 
       "Parent" : "1", 
       "attr" : "abc", 
       "children" : [{ 
          "Id" : "3", 
          "Name" : "abc", 
          "Parent" : "2", 
          "attr" : "abc", 
          "children" : [] 
         }, { 
          "Id" : "4", 
          "Name" : "abc", 
          "Parent" : "2", 
          "attr" : "abc", 
          "children" : [] 
         }] 
      }] 
}] 
+1

Great Work Arun !! Grazie mille! – LastTribunal

+0

Arun, sai come posso rinominare l'attributo "bambini" come "elementi"? – LastTribunal

+0

@ 655321 vedere l'aggiornamento –

2
function convert(rows) { 
    function exists(rows, Parent) { 
      for (var i = 0; i < rows.length; i++) { 
        if (rows[i].Id == Parent) return true; 
      } 
      return false; 
    } 
    var nodes = []; 
    // get the top level nodes 
    for (var i = 0; i < rows.length; i++) { 
      var row = rows[i]; 
      if (!exists(rows, row.Parent)) { 
        nodes.push({ 
          id: row.Id, 
          name: row.Name, 
          attr: row.attr 
        }); 
      } 
    } 
    var toDo = []; 
    for (var i = 0; i < nodes.length; i++) { 
      toDo.push(nodes[i]); 
    } 
    while (toDo.length) { 
      var node = toDo.shift(); 
      // the parent node 
      // get the children nodes 
      for (var i = 0; i < rows.length; i++) { 
        var row = rows[i]; 
        if (row.Parent == node.Id) { 
          var child = { 
            Id: row.Id, 
            Name: row.Name, 
            attr: row.attr 
          }; 
          if (node.options) { 
            node.options.push(child); 
          } else { 
            node.options = [child]; 
          } 
          toDo.push(child); 
        } 
      } 
    } 
    return nodes;} 
+0

Penso che questa risposta sia migliore. Anche se i nodi di livello superiore non sono il primo elemento dell'array, questo funziona correttamente. –

3
risposta di

@Arun P Johny è buono, ma ha un problema , quando l'array non è ordinato, svuoterà i sotto-alberi. L'ho aggiornato come questo.

var arry = [ 
       { "Id": "5", "Name": "abc", "Parent": "3", "attr": "abc" }, 
       { "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" }, 
       { "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }, 
       { "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" }, 
       { "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" } 
       ]; 

function convert(array){ 
    var map = {} 
    for(var i = 0; i < array.length; i++){ 
     var obj = array[i] 
     if(!(obj.Id in map)){ 
      map[obj.Id] = obj 
      map[obj.Id].children = [] 
     } 

     if(typeof map[obj.Id].Name == 'undefined'){ 
      map[obj.Id].Id = obj.Id 
      map[obj.Id].Name = obj.Name 
      map[obj.Id].attr = obj.attr 
      map[obj.Id].Parent= obj.Parent 
     } 

     var parent = obj.Parent || '-'; 
     if(!(parent in map)){ 
      map[parent] = {} 
      map[parent].children = [] 
     } 

     map[parent].children.push(map[obj.Id]) 
    } 
    return map['-'] 
} 
console.log(JSON.stringify(convert(arry))) 

il risultato è come questo:

{ 
    "children": [ 
    { 
     "children": [ 
     { 
      "Id": "2", 
      "Name": "abc", 
      "Parent": "1", 
      "attr": "abc", 
      "children": [ 
      { 
       "Id": "4", 
       "Name": "abc", 
       "Parent": "2", 
       "attr": "abc", 
       "children": [] 
      }, 
      { 
       "children": [ 
       { 
        "Id": "5", 
        "Name": "abc", 
        "Parent": "3", 
        "attr": "abc", 
        "children": [] 
       } 
       ], 
       "Id": "3", 
       "Name": "abc", 
       "attr": "abc", 
       "Parent": "2" 
      } 
      ] 
     } 
     ], 
     "Id": "1", 
     "Name": "abc", 
     "attr": "abc", 
     "Parent": "" 
    } 
    ] 
} 
+0

Ottima risposta! ... –

0

// provare come questo ...................

function prepareFlatArrayListToTreeViewList(arry) { 
    var treeviewList= angular.copy(flatListToTreeViewData(arry)); 
    return treeviewList; 
} 

// restituire dati in formato json

function flatListToTreeViewData(dataList) { 
    var tree = [], 
     mappedArr = {}, 
     arrElem, 
     mappedElem; 

    // First map the nodes of the array to an object -> create a hash table. 
    for (var i = 0, len = dataList.length; i < len; i++) { 
     arrElem = dataList[i]; 
     mappedArr[arrElem.id] = arrElem; 
     mappedArr[arrElem.id]['children'] = []; 
    } 

    for (var id in mappedArr) { 
     if (mappedArr.hasOwnProperty(id)) { 
      mappedElem = mappedArr[id]; 

      // If the element is not at the root level, add it to its parent array of children. 
      if (mappedElem.parentID) { 
       mappedArr[mappedElem['parentID']]['children'].push(mappedElem); 
      } 
       // If the element is at the root level, add it to first level elements array. 
      else { 
       tree.push(mappedElem); 
      } 
     } 
    } 
    return tree; 
}