对象根据id合并问题

遇到一个结构比较复杂的对象,夜不能寐,求大神协助

基本结构大概是这样:

[{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                dId: 4444,
                num: 2
            }]
        }]
    }]
}]

其中每层List中可以包含多个下级对象,比如:

[{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                dId: 4444,
                num: 2
            }, {
                dId: 5555,
                num: 1
            }]
        }]
    }, {
        bId: 33,
        bList: [{
                cId: 321,
                cList: [{
                    dId: 4123,
                    num: 1
                }]
            },
            {
                cId: 987,
                cList: [{
                    dId: 4193,
                    num: 1
                }]
            }
        ]
    }]
}]

需求是,将两个这样的结构合并,分别判断每层的id是否相同,不同就push到相应的list中,相同就继续往下遍历,(如果最后dId也相同,则num++)比如:

var a = [{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                dId: 4444,
                num: 2
            },
            {
                dId: 5555,
                num: 1
            }]
        }]
    }]
}]

var b = [{
    aId: 1,
    aList: [{
            bId: 22,
            bList: [{
                cId: 333,
                cList: [{
                    dId: 6666,
                    num: 1
                }]
            }]
        },
        {
            bId: 33,
            bList: [{
                cId: 987,
                cList: [{
                    dId: 5678,
                    num: 1
                }]
            }]
        }
    ]
}]


console.log(reduce(a,b));

输出:

[{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                    dId: 4444,
                    num: 2
                },
                {
                    dId: 5555,
                    num: 1
                },
                {
                    dId: 6666,
                    num: 1
                }
            ]
        }]
    }, {
        bId: 33,
        bList: [{
            cId: 987,
            cList: [{
                dId: 5678,
                num: 1
            }]
        }]
    }]
}]

es6、5不限。

阅读 1.9k
1 个回答

把题主的例子稍微复杂了下,考虑了全部相同导致 num++ 的情况,另,优化了代码

var a = [{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                    dId: 4444,
                    num: 2
                },
                {
                    dId: 5555,
                    num: 1
                }
            ]
        }]
    }]
}];

var b = [{
    aId: 1,
    aList: [{
            bId: 22,
            bList: [{
                cId: 333,
                cList: [{
                    dId: 5555,
                    num: 1
                }, {
                    dId: 6666,
                    num: 1
                }]
            }]
        },
        {
            bId: 33,
            bList: [{
                cId: 987,
                cList: [{
                    dId: 5678,
                    num: 1
                }]
            }]
        }
    ]
}];

var result = [{
    aId: 1,
    aList: [{
        bId: 22,
        bList: [{
            cId: 333,
            cList: [{
                    dId: 4444,
                    num: 2
                },
                {
                    dId: 5555,
                    num: 2
                },
                {
                    dId: 6666,
                    num: 1
                }
            ]
        }]
    }, {
        bId: 33,
        bList: [{
            cId: 987,
            cList: [{
                dId: 5678,
                num: 1
            }]
        }]
    }]
}];


console.log(JSON.stringify(reduce(a, b)) === JSON.stringify(result)); //true

function reduce(a, b) {
    let levelArr = ['a', 'b', 'c', 'd'],
        //如果后面还有 e,f,g 只需要修改这里就行;
        result = iterateCompareId(a, b, undefined, 'a');

    function iterateCompareId(listA, listB, listTemp, level) {
        // 保存 listA 的副本,后期把 listB 中的数据逐步加给 listTemp,作为函数返回值;
        // 注意这里 listTemp 反复迭代,但始终指向的是保存在内存里的同一个对象,一直在修改 listTemp 的数据;
        listTemp = listTemp === undefined ? JSON.parse(JSON.stringify(listA)) : listTemp;
        listB.forEach((objB, indexB) => {

            //求出当前 level 中, listB 中项在 listA 中的索引,不存在,则返回 -1

            let IndexOfIdInA = listA.findIndex((objA, indexA) => {
                return objA[level + 'Id'] === objB[level + 'Id'];
            });

            //如果当前 level 中,listA 中 没有 listB  的 id,把 listB 这个level的数据拷给 listTemp

            if (IndexOfIdInA === -1) {
                listTemp.push(objB);
            } else {

                //如果有,判断是否到最后一层
                //不是最后一层,切换到下一层 level,继续    
                //是最后一层,listTemp 当前层 num+=1;

                if (levelArr.indexOf(level) != levelArr.length - 1) {
                    iterateCompareId(listA[IndexOfIdInA][level + 'List'], objB[level + 'List'], listTemp[IndexOfIdInA][level + 'List'], levelArr[levelArr.indexOf(level) + 1]);
                } else {
                    listTemp[IndexOfIdInA].num += 1;
                }

            }
        });
        return listTemp;
    }

    return result;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题