Javascript 从具有平面路径的对象数组生成嵌套对象

Javascript 从具有平面路径的对象数组生成嵌套对象,javascript,algorithm,tree,Javascript,Algorithm,Tree,我试图将一个对象数组(数组中的每个对象都有路径和id)转换为表示该路径的树。例如,[{path:'foo/bar/baz',id:1}] [ { “路径”:“foo”, “儿童”:[ { “路径”:“条”, “儿童”:[ { “路径”:“baz”, “儿童”:[…], } ] } ] } ] 到目前为止,我有以下代码: 常量pathObjs=[ {id:1,路径:'foo/bar/baz'}, ]; 常量结果=[]; 常量级别={result}; 对于(pathObjs的p){ p、 pat

我试图将一个对象数组(数组中的每个对象都有路径和id)转换为表示该路径的树。例如,
[{path:'foo/bar/baz',id:1}]

[
{
“路径”:“foo”,
“儿童”:[
{
“路径”:“条”,
“儿童”:[
{
“路径”:“baz”,
“儿童”:[…],
}
]
}
]
}
]
到目前为止,我有以下代码:


常量pathObjs=[
{id:1,路径:'foo/bar/baz'},
];
常量结果=[];
常量级别={result};
对于(pathObjs的p){
p、 path.split('/').reduce((r,path)=>{
如果(!r[path]){
r[path]={result:[]};
常量p={path,子项:r[path].result};
r、 结果:推挤(p);
}
返回r[path];
},水平);
}
我不知道如何在正确的级别分配每个路径的
id
,以便最终结果如下所示:

[
{
“路径”:“foo”,
“儿童”:[
{
“路径”:“条”,
“儿童”:[
{
“路径”:“baz”,
“儿童”:[…],
//如何添加这个家伙在这里!
“id”:1,
}
]
}
]
}
]

有人能把我推向正确的方向吗。

这个解决方案重新构造了您的原始代码。主要区别在于路径列表是反向的,因此我们从叶节点而不是根节点开始

有一个明确的检查,看看我们是否在第一个索引(我们可以假设它是叶)。或者,您可以检查是否定义了
result
,如果您愿意,可以依赖于它而不是索引

constpathobjects=[{id:1,路径:“foo/bar/baz”}];
常量结果=[];
for(让pathObjects的{id,path}){
const obj=路径
.拆分(“/”)
.reverse()
.reduce((结果、路径、索引)=>{
常量节点={
路径
子项:结果?[结果]:[]
};
如果(索引==0){
node.id=id;
}
返回节点;
},空);
结果:推送(obj);
}

控制台日志(结果)
reduce
回调中,使用
reduce
完成后可访问的变量,而不是将
const p
设置为局部变量,以便您可以访问最后分配的对象以添加附加属性

因此,改变:

      const p = { path, children: r[path].result };
      r.result.push(p);
致:

并将
last
定义为
块的
范围内的局部变量。
reduce
完成后,您可以使用
对象。分配
以变异该“叶”对象,添加额外的属性:

  Object.assign(last, rest); // rest is whatever needs to be added.
因此,您的代码可以修改如下:

const result = [];
const level = { result };

for (p of pathObjs) {
  let last; // This will be the latest added object
  let { path, ...rest } = p; // Extract the path and the other properties
  path.split('/').reduce((r, path, i, {length}) => {
    if (!r[path]) {
      r[path] = { result: [] };

      last = { path, children: r[path].result };

      r.result.push(last);
    }

    return r[path];
  }, level);
  Object.assign(last, rest); // Extend with the extra properties.
}

嗯,我明白了。尽管上述代码的输出具有重复的父节点。例如,输入
[{id:1,路径:“foo/bar/baz”},{id:2,路径:“foo/bar/bax”}]
而不是
foo.bar
有两个孩子
[baz,baz]
,有两个单独的foo.bar和两个不同的孩子?muchas gracias
const result = [];
const level = { result };

for (p of pathObjs) {
  let last; // This will be the latest added object
  let { path, ...rest } = p; // Extract the path and the other properties
  path.split('/').reduce((r, path, i, {length}) => {
    if (!r[path]) {
      r[path] = { result: [] };

      last = { path, children: r[path].result };

      r.result.push(last);
    }

    return r[path];
  }, level);
  Object.assign(last, rest); // Extend with the extra properties.
}