【问题标题】:Hierarchical json from flat with parent ID来自具有父 ID 的平面的分层 json
【发布时间】:2013-02-28 20:28:08
【问题描述】:

http://jsfiddle.net/eYgGK/

我从另一个帖子偷了这个脚本:

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"
           
        }]
    }]
}]

我需要首先摆脱“价值”包装,其次是空子节点。 我知道我可以编写一个清理脚本,但这不是最佳实践。 如果有人知道如何修复或建议不同的脚本,那就太好了!

谢谢

【问题讨论】:

    标签: javascript json hierarchical


    【解决方案1】:

    试试类似的东西

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

    【讨论】:

    • Arun,你知道如何将“children”属性标题重命名为“items”吗?
    • 如果我更改数组元素的顺序,它将不起作用。例如,如果我将数组元素的位置(即 Id 1)更改为数组的最后一个,则此方法将不起作用。 jsfiddle.net/MkTA6/146。有什么办法也可以解决这个问题。
    • @JetsonJohn 你有没有发现,如果数据是 id 不是连续的,我也有类似的要求。 id不是连续的,所以所有的孩子都是空的
    • @ArunPJohny 我对在 json 对象中多一层嵌套的类似问题感到震惊。我在这里发布了一个与之相关的问题 - stackoverflow.com/questions/49204904/…。你能建议如何解决它。
    【解决方案2】:

    @Arun P Johny 的回答很好,但是有一个问题,当数组没有排序时,会刷新子树。我是这样更新的。

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

    【讨论】:

      【解决方案3】:
      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;}
      

      【讨论】:

      • 我认为这个答案更好。即使顶级节点不是数组的第一个元素,也可以正常工作。
      【解决方案4】:

      改进版,接受参数。

      function convert(rows, options) {
          var options = options || {};
          var idProp = options.id || 'id';
          var parentProp = options.parent || 'parent';
          var childProp = options.children || 'children';
      
          function exists(rows, parent) {
              for (var i = 0; i < rows.length; i++) {
                  if (rows[i][idProp] == 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[parentProp])) {
                  nodes.push(Object.assign({}, row));
              }
          }
      
          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[parentProp] == node[idProp]) {
                      var child = Object.assign({}, row);
                      node[childProp] = node[childProp] || [];
                      node[childProp].push(child);
                      toDo.push(child);
                  }
              }
          }
      
          return nodes;
      }

      // Usage
      var data = [...];
      convert(data);
      // Or
      convert(data, { id: 'Id', parent: 'Parent', children: 'Children' });

      【讨论】:

        【解决方案5】:

        // 像这样尝试......

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-04-13
          • 1970-01-01
          • 2016-09-12
          • 2017-10-16
          • 2020-03-08
          • 2017-04-16
          • 1970-01-01
          相关资源
          最近更新 更多