Javascript 如何根据属性值从对象列表创建嵌套对象

Javascript 如何根据属性值从对象列表创建嵌套对象,javascript,Javascript,我面临解析API并将响应组合到适当对象中的真正问题。我尝试过很多解决方案,但在很多方面都失败了 如果有这样一个问题的解决方案的答案-请提供一个链接。因为我发现了很多关于如何筑巢的问题,但没有人知道如何使用移动 到目前为止,我的回答如下: [ {path: "1.0.0"}, {path: "1.1"}, {path: "13"}, {path: "2"}, {path: "1"}, {path: "2.0.0.1"}, {path: "3.0.1.1"} ] 我需要转变成这样:

我面临解析API并将响应组合到适当对象中的真正问题。我尝试过很多解决方案,但在很多方面都失败了

如果有这样一个问题的解决方案的答案-请提供一个链接。因为我发现了很多关于如何筑巢的问题,但没有人知道如何使用移动

到目前为止,我的回答如下:

[
 {path: "1.0.0"},
 {path: "1.1"},
 {path: "13"},
 {path: "2"},
 {path: "1"},
 {path: "2.0.0.1"},
 {path: "3.0.1.1"}
]
我需要转变成这样:

 [  
   {  
      path:"1",
      subCategories:[  
         {  
            path:"1.0.0",
            subcategories:[]
         },
         {  
            path:"1.1",
            subcategories:[
                           {
                             path:"1.1.0",
                             subcategories: []
                           }
           ]
         },
      ]
   },
   {  
      path:"13",
      subcategories:[]
   },
   {  
      path:"2",
      subcategories:[  
         {  
            path:"2.0.0.1",
            subcategories:[]
         }
      ]
   },
   {  
      path:"3.0.1.1",
      subcategories:[]
   },
]
主要的复杂性在于,在服务器端,我们可以隐藏任何类别,在这种情况下,子类别应该取代父类别。父对象和子对象用点分隔


如果你能帮助我,我将不胜感激。谢谢。

这只支持两个级别,如果需要支持任意数量的嵌套,则需要递归解决方案

var o=[{
路径:“1.0.0”
},
{
路径:“1.1”
},
{
路径:“13”
},
{
路径:“2”
},
{
路径:“1”
},
{
路径:“1.1.0”
},
{
路径:“2.0.0.1”
},
{
路径:“3.0.1.1”
}
]
const result=o.reduce((备注,d)=>{
const key=d.path.split('.')[0]
备忘录[键]?备忘录[键]。按(d):备忘录[键]=[d]
回执
}, [])
.filter(布尔值)
.map(items=>items.map(d=>d.path).sort())
.map(项目=>items.reduce((备忘录,d)=>{
常量数据传输={
路径:d,
子类别:[]
}
如果(!memo.path){
返回数据传输
}
const parent=memo.subCategories.find(c=>d.startsWith(c.path))
如果(家长){
父类.子类.推送(数据传输)
}否则{
备注.子类别.推送(数据传输)
}
回执
}, {}))

log(result)
您可以采用递归方法,分两步收集相同级别的项目,然后创建对象

函数getTree(数组,前缀=[]){ 函数getCommon(数组){ 返回数组.reduce((a,b)=>{ var l=0; 而(a[l]===b[l]&&l在a中)l++; 返回a.slice(0,l); }); } var l=array.length&&getCommon(数组)+1; 返回数组 .减少((r,a)=>{ var left=a.切片(0,l), 右=a.slice(l), temp=r.find([b])=>left.join('.')==b.slice(0,l).join('.'); 如果(临时){ 温度[1]。推送(右); }否则{ r、 推(左[右]); } 返回r; }, []) .map([p,sub])=>{ var path=prefix.concat(p,sub.length==1?sub[0]:[]); 返回{ 路径:path.join('.'), 子类别:子长度===1 ? [] :getTree(sub.filter({length})=>length),path) }; }); } var data=[{path:“1.0.0”},{path:“1.1”},{path:“1.1.0”},{path:“13”},{path:“2”},{path:“1”},{path:“2.0.0.1”},{path:“3.0.1.1”}], tree=getTree(data.map({path})=>path.split('.'); 控制台日志(树)
作为控制台包装{max height:100%!important;top:0;}
为什么
1.0.0
而不是
1.0
,这会更好地描述级别。。。?您尝试了什么?因为具有1.0路径的类别隐藏在服务器端。它存在,但我没有收到它。所以1.0.0是一个隐藏的1.0的孩子。这样,1.0.0应该取代家长的位置
1.1.0
不在您的数据中,但在您的结果中。@MarkMeyer您说得对。是我的错,我打错了。既然我不能编辑这篇文章,让我们假装它在那里;)我能理解为什么我的问题被否决了。我没有提供任何我的解决方案,但我在一开始就坚持使用排序逻辑,并且没有关于它的代码发布。我不在乎rep point,但还是伙计们,你们能对那些刚开始编程或不是英语母语的人更友好一些吗。祝你身体健康,好运。