2013-03-13 95 views
8

http://jsfiddle.net/eYgGK/層次JSON與父ID

我偷了這個腳本從不同的職位:

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; 
    } 

此腳本生成:

[{ 
    "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": [] 
     }] 
    }] 
}] 

我正在尋找的是:

[{ 
    "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" 

     }] 
    }] 
}] 

我需要主要擺脫「價值」包裝,其次是空的子節點。 我知道我可以寫一個清理腳本,但那不會是最佳實踐。 如果有人知道如何修復或建議一個不同的腳本,那將會很棒!

感謝

回答

17

試着這麼做

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) 

演示:Fiddle

結果

[{ 
    "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 !!太感謝了! – LastTribunal 2013-03-13 03:22:55

+0

Arun,你知道我可以如何將「children」屬性tittle重命名爲「items」? – LastTribunal 2013-03-14 18:24:50

+0

@ 655321查看更新 – 2013-03-15 00:00:59

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

我認爲這個答案是更好的。 即使頂級節點不是數組的第一個元素,也可以正常工作。 – 2015-01-14 07:29:17

3

@Arun P佐尼的回答是不錯的,但它有一個問題, 什麼時候 數組沒有排序,它會刷新子樹。我更新了它。

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

的結果是這樣的:

{ 
    "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

很好的答案!... – 2017-02-28 16:16:45

0

//嘗試這樣...................

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

//返回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; 
}