多层次object, 返回每一层最后一级组成新object

博客讲述了如何处理包含多级child属性的对象集合,尤其是当child为空时,如何通过递归方法将其整合到同一数组中。在处理大规模数据和模拟延迟情况下,原有的递归方式会导致异步问题,作者提出了一个优化方案,即通过有序递归,确保先处理第一级,再处理下一级,以此避免异步问题。这种方法保证了在延迟情况下也能正确输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有这么一个对象集 (子集有多少个 未知)

let result = [
    {
        name:"aaa",
        id:"aaa111",
        child:[
            {
                name:"bbb1",
                id:"bbb111",
                child:[
                    {
                        child:[],
                        name:"last1",
                        id:"111"
                    },
                    {
                        child:[],
                        name:"last2",
                        id:"222"
                    },
                    {
                        child:[],
                        name:"last3",
                        id:"333"
                    },
                    {
                        child:[],
                        name:"last4",
                        id:"444"
                    },
                    {
                        child:[],
                        name:"last5",
                        id:"555"
                    }
                ]
            },
            {
                name:"bbb2",
                id:"bbb222",
                child:[]
            }
        ]
    }
    
];

每一级都有一个 child , 需求是, 将每一级 child 为空的数据, 整合到同一个 arr 中

如何做到呢? 

肯定是使用 arr.map  的方式 递归判断

let f = (obj,f_) =>{
    obj.map(item=>{
        if(item.child.length == 0){
            f_(item);
        }else f(item.child,f_);
    })   
}

 

 看起来是没问题的, 那我们假设递归数量大, 又或者出现延迟

let f = (obj,f_) =>{
    obj.map(item=>{
        if(item.child.length == 0){
           setTimeout(()=>{
                f_(item);
           },30)
        }else f(item.child,f_);
    })   
}

 

 可以看到, 模拟了延迟后, arr 打印的是 [] , 根本原因是 异步了

那么怎么处理呢 ?

let f = (obj,f_) =>{
    let o_ = [];
    obj.map((item,index)=>{
        if(index == (obj.length -1)){
            if(item.child.length == 0){
                f_(item,o_.length == 0);
                if(o_.length != 0) f(o_,f_);
            }else {
                if(index == 0) o_ = o_.concat(item.child);
                f(o_,f_);
            }
        }else{
            if(item.child.length == 0){
                f_(item,false);
            }else {
               o_ = o_.concat(item.child);
            }
        }
    })   
}

 优化了一下后, 可以看到, 正常输出是没有问题的

那我们再来延迟一下

let f = (obj,f_) =>{
    let o_ = [];
    obj.map((item,index)=>{
        if(index == (obj.length -1)){
            if(item.child.length == 0){
                // 增加延迟
                setTimeout(()=>{
                    f_(item,o_.length == 0);
                },30)
                if(o_.length != 0) f(o_,f_);
            }else {
                if(index == 0) o_ = o_.concat(item.child);
                f(o_,f_);
            }
        }else{
            if(item.child.length == 0){
                // 增加延迟
                setTimeout(()=>{
                     f_(item,false);
                },30)
            }else {
               o_ = o_.concat(item.child);
            }
        }
    })   
}

 

 OK , 没得问题 !

原理是啥呢,  其实是将原来的 无序递归, 改成了, 有序递归, 先递归第一级, 在递归第二级, 依次类推, 直到没有下一级, 在 return true, 通知递归完成, 就可以避免 异步的问题了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值