Javascript 我如何通过它们的';s parentId和Id。

Javascript 我如何通过它们的';s parentId和Id。,javascript,arrays,object,tree,Javascript,Arrays,Object,Tree,我有一个这样的平面阵列,我应该为它构建一个平面阵列。如果pid不为null,则该对象将是其父对象的子属性。我该怎么做 var a = [ {id: 1, pid: null}, {id: 2, pid: 1}, {id: 3, pid: 1}, {id: 4, pid: 3}, {id: 5, pid: 3} ]; 预期产出: var result = [{id: 1, chil

我有一个这样的平面阵列,我应该为它构建一个平面阵列。如果pid不为null,则该对象将是其父对象的子属性。我该怎么做

    var a = [
        {id: 1, pid: null}, 
        {id: 2, pid: 1}, 
        {id: 3, pid: 1}, 
        {id: 4, pid: 3}, 
        {id: 5, pid: 3}
     ];
预期产出:

     var result = [{id: 1, children: [
        {id: 2, children: []},
        {id: 3, children: [{id: 4}, {id: 5}]}
    ]}]
您可以使用
reduce()
方法创建递归函数

var a=[{id:1,pid:null},{id:2,pid:1},{id:3,pid:1},{id:4,pid:3},{id:5,pid:3}];
函数树(数据、父级){
返回数据.reduce((r,{id,pid})=>{
如果(父项==pid){
常量obj={id}
const children=树(数据,id);
if(children.length)obj.children=children;
r、 推送(obj)
}
返回r;
}, [])
}
常量结果=树(a,空);

控制台日志(结果)您可以使用单循环方法,该方法也适用于未排序的数组

var a=[{id:1,pid:null},{id:2,pid:1},{id:3,pid:1},{id:4,pid:3},{id:5,pid:3}],
树=函数(数据,根){
返回data.reduce(函数(o,{id,pid}){
o[id]=o[id]|{id};
o[pid]=o[pid]|{id:pid};
o[pid]。children=o[pid]。children | |[];
o[pid].children.push(o[id]);
返回o;
},{}[root]。子对象;
}(a)无效;
控制台日志(树)

.as console wrapper{max height:100%!important;top:0;}
使用reduce-here的两个答案都很好,一个小问题是都有多遍,注意:如果树很大,将有很多线性搜索

解决这个问题的一个方法是先绘制地图,然后展平地图。。嗯,实际上,这里的flatte可能是个错误的词,可能是expand:)但是你明白了

下面是一个例子

const a=[
{id:1,pid:null},
{id:2,pid:1},
{id:3,pid:1},
{id:4,pid:3},
{id:5,pid:3}
];
函数平台(映射、父级){
const g=map.get(父级);
常数ret=[];
如果(g){
for(g的常数id){
常数k={id};
后推(k);
const sub=flatern(地图,id);
如果(sub)k.children=sub;
}
返回ret;
}
返回null;
}
功能树(a){
常数m=新映射();
a、 forEach((i)=>{
常数g=m.get(i.pid);
if(!g){
m、 设置(i.pid,[i.id]);
}否则{
g、 推送(i.id);
}
});
返回平面(m,空);
}
console.log(树(a))
。作为控制台包装{最大高度:100%!重要;顶部:0;}

今天学会了这个方法,我觉得这是最好的

了吗?谢谢。但我想知道,如果我希望我的输出完全像“var result=…..”一样,我该怎么办。我的意思是,从“var result=”开始,不确定你在问什么。现在你的方法的输出是一个数组树。如果我想要像“var result=…(数组树在这里)”这样的格式,该怎么办呢?顺便说一句,我的方法使用了一个对象,由于哈希表的缘故,没有进行搜索。访问权限是O(1)。@NinaScholz很好,必须承认并没有真正详细地检查代码。。你的看起来比我的容易所以我要投你的。。我会把我的放在这里给那些觉得它更容易阅读/理解的人。嗨,非常感谢。但是我很难理解“if(sub)k.children=sub;”是什么意思,你能解释一下为什么sub上有一个()吗?它只是指是否有子项,并且它们作为子项。
    var a = [
        {id: 1, pid: null}, 
        {id: 2, pid: 1}, 
        {id: 3, pid: 1}, 
        {id: 4, pid: 3}, 
        {id: 5, pid: 3}
    ];

    function processToTree(data) {
        const map = {};
        data.forEach(item => {
            map[item.id] = item;
            item.children = [];
        });

        const roots = [];
        data.forEach(item => {
            const parent = map[item.pid];
            if (parent) {
                parent.children.push(item);
            }
            else {
                roots.push(item);
            }
        });
        return roots;
    }