【问题标题】:Flat array to tree array using lodash.js使用 lodash.js 将平面数组转换为树数组
【发布时间】:2016-04-19 13:34:32
【问题描述】:


我正在尝试将平面数组转换为树数组,因为我将使用 jsTree 中的数据。我还需要将“名称”等键名转换为“文本”。
我想使用 lodash.js,但我是 lodash 的新手。我搜索了解决方案,但找不到适合我的情况。
那么你能帮忙吗?我的平面数组数据如下:

[
    {
        Id:1,
        Name: 'name1',
        Parent: 0
    },
    {
        Id:2,
        Name: 'name2',
        Parent: 1
    },
    {
        Id:3,
        Name: 'name3',
        Parent: 2
    },
    {
        Id:4,
        Name: 'name4',
        Parent: 1
    },
    {
        Id:5,
        Name: 'name5',
        Parent: 1
    },
    {
        Id:6,
        Name: 'name6',
        Parent: 5
    }
]

我想要像这样的树数据:

{
    "id": 1, 
    "text" : "name1", 
    "children" : [
        { 
            "id": 2, 
            "text" : "name2", 
            "children" : [{
                "id": 3,
                "text": "name3"
            }] 
        },
        { 
            "id": 4, 
            "text" : "name4" 
        },
        { 
            "id": 5, 
            "text" : "name5",
            "children" : [{
                "id": 6,
                "text": "name6"
            }]  
        }
    ]
}

提前谢谢你

【问题讨论】:

  • 数据是否已排序 - 父母是否明智?
  • @NinaScholz 是的,我们可以这么认为。

标签: javascript lodash


【解决方案1】:

这是针对未排序数据的纯 Javascript 提案。

var data = [{ Id: 1, Name: 'name1', Parent: 0 }, { Id: 2, Name: 'name2', Parent: 1 }, { Id: 3, Name: 'name3', Parent: 2 }, { Id: 4, Name: 'name4', Parent: 1 }, { Id: 5, Name: 'name5', Parent: 1 }, { Id: 6, Name: 'name6', Parent: 5 }],
    tree = function (data, root) {
        var r;
        data.forEach(function (a) {
            this[a.Id] = { id: a.Id, text: a.Name, children: this[a.Id] && this[a.Id].children };
            if (a.Parent === root) {
                r = this[a.Id];
            } else {
                this[a.Parent] = this[a.Parent] || {};
                this[a.Parent].children = this[a.Parent].children || [];
                this[a.Parent].children.push(this[a.Id]);
            }
        }, Object.create(null));
        return r;
    }(data, 0);

document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');

【讨论】:

    【解决方案2】:

    如果您不确定孩子是否不能出现在父母之前,那么您可以使用以下代码:

    var t = [{ Id: 1, Name: 'name1', Parent: 0 }, { Id: 2, Name: 'name2', Parent: 1 }, { Id: 3, Name: 'name3', Parent: 2 }, { Id: 4, Name: 'name4', Parent: 1 }, { Id: 5, Name: 'name5', Parent: 1 }, { Id: 6, Name: 'name6', Parent: 5 }];
    
    var elements = [];
    t.forEach(function(element) {
    	elements[element.Id] = {
    		id: element.Id,
    		text: element.Name,
    		parent: element.Parent,
    		children: []
    	}
    });
    
    elements.forEach(function(element) {
    	elements[element.parent] && elements[element.parent].children.push(element);
    	delete element.parent;
    })
    
    document.write(['<pre>', JSON.stringify(elements[1], 0, 3), '</pre>'].join(''));

    【讨论】:

      【解决方案3】:

      下面的函数从对象列表构建一棵树。 它对任何格式都不严格。

      function buildTree(flatList, idFieldName, parentKeyFieldName, fieldNameForChildren) {
          var rootElements = [];
          var lookup = {};
      
          flatList.forEach(function (flatItem) {
            var itemId = flatItem[idFieldName];
            lookup[itemId] = flatItem;
            flatItem[fieldNameForChildren] = [];
          });
      
          flatList.forEach(function (flatItem) {
            var parentKey = flatItem[parentKeyFieldName];
            if (parentKey != null) {
              var parentObject = lookup[flatItem[parentKeyFieldName]];
              if(parentObject){
                parentObject[fieldNameForChildren].push(flatItem);
              }else{
                rootElements.push(flatItem);
              }
            } else {
              rootElements.push(flatItem);
            }
      
          });
      
          return rootElements;
        }
      

      Here is a fiddle 使用您的示例作为输入。

      原文出处comes from this answer

      【讨论】:

        【解决方案4】:

        有点像

        return _(data).map(function(val) { val.children = []; })
        .map(function(val, key) {
            data[val.parent].children.push(val);
        });
        

        滥用数组索引。您可能需要先在源数据中构建一个从Idindex 的辅助映射。

        这只是 Array.map 的普通用法,因此此解决方案不需要 lodash。

        【讨论】:

          猜你喜欢
          • 2023-03-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-22
          • 2020-05-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多