用Javascript创建嵌套数组

时间:2019-05-13 15:59:41

标签: javascript

我正在尝试将数据从API转换为我的需求。想从普通数组创建一个嵌套数组。我想按parentId属性对元素进行分组,如果parentId不存在,我会将其作为根。 id的值是唯一的。像这样(原始数据):

[
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
]

已转换的数据:

  const results = [
    {
      id: 1,
      name: "sensor",
      children: [
        { id: 2, name: "sensor", parent: 1 },
        {
          id: 3,
          name: "sensor",
          parent: 1,
          children: [{ id: 4, name: "sensor", parent: 3 }]
        }
      ]
    },
    { id: 5, name: "sensor", children: [{ id: 6, name: "sensor", parent: 5 }] }
  ];

我找到了此递归方法,但它假定数组中每个元素的父属性都存在。在我的示例中,根级别元素将没有父属性。

function getNestedChildren(arr, parent) {
    var out = []
    for(var i in arr) {
        if(arr[i].parent == parent) {
            var children = getNestedChildren(arr, arr[i].id)

            if(children.length) {
                arr[i].children = children
            }
            out.push(arr[i])
        }
    }
    return out
}

4 个答案:

答案 0 :(得分:3)

您可以采用一种使用两种关系的方法,一种是从孩子到父母,反之亦然。最后,获取根节点的子代。

这种方法适用于未排序的数据。

var data = [{ id: 1, name: 'sensor' }, { id: 2, name: 'sensor', parent: 1 }, { id: 3, name: 'sensor', parent: 1 }, { id: 4, name: 'sensor', parent: 3 }, { id: 5, name: 'sensor' }, { id: 6, name: 'sensor', parent: 5 }],
    tree = function (data, root) {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || {}, o);
            t[o.parent] = t[o.parent] || {};
            t[o.parent].children = t[o.parent].children || [];
            t[o.parent].children.push(t[o.id]);
        });
        return t[root].children;
    }(data, undefined);
    
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

使用for循环遍历每个项目。 检查父级属性是否存在(或具有值)。 如果不是它的子项。将其附加到适当的父级。

检查属性是否存在:

var myProp = 'prop';
if (myObj.hasOwnProperty(myProp)) {
  alert("yes, i have that property");
}

答案 2 :(得分:0)

尝试

let h={}, r=[]; // result in r
d.forEach(x=> (h[x.id]=x, x.children=[]) );
d.forEach(x=> x.parent ? h[x.parent].children.push(x) : r.push(x) );

let d = [
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
];

let h = {},r = []; // result in r
d.forEach(x => (h[x.id] = x, x.children = []));
d.forEach(x => x.parent ? h[x.parent].children.push(x) : r.push(x));

console.log(r);

答案 3 :(得分:0)

鉴于信息量有限(如果添加更多信息,信息将会更新)。

在给定数据条目数组的情况下,该算法将检查条目是否具有父条目,并且该父条目是否存在,在这种情况下,我们要将条目添加到父条目的子条目数组中,否则将条目添加为家长。

var dataFromAPI = [
    {id: 1, name: 'sensor'},
    {id: 2, name: 'sensor', parent: 1},
    {id: 3, name: 'sensor', parent: 1},
    {id: 4, name: 'sensor', parent: 3},
    {id: 5, name: 'sensor'},
    {id: 6, name: 'sensor', parent: 5}
];


var transformedData = { };

dataFromAPI.forEach(function(entry){

    if(entry.parent !== undefined && entry.parent in transformedData) {
       transformedData[entry.parent].children.push(entry);
    } else {
        entry["children"] = [];
        transformedData[entry.id] = entry;
    }
});

console.log(transformedData);
请注意:

在此算法/代码中有两个假设。它假定所有父项条目都在其子项条目之前存在。它也只占两个级别(父级或子级),这意味着子级不能充当父级(否则您必须将子级存储为object而不是array