鍍金池/ 問答/HTML/ 對(duì)象根據(jù)id合并問題

對(duì)象根據(jù)id合并問題

遇到一個(gè)結(jié)構(gòu)比較復(fù)雜的對(duì)象,夜不能寐,求大神協(xié)助

基本結(jié)構(gòu)大概是這樣:

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

其中每層List中可以包含多個(gè)下級(jí)對(duì)象,比如:

[{
    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
                }]
            }
        ]
    }]
}]

需求是,將兩個(gè)這樣的結(jié)構(gòu)合并,分別判斷每層的id是否相同,不同就push到相應(yīng)的list中,相同就繼續(xù)往下遍歷,(如果最后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不限。

回答
編輯回答
涼薄

把題主的例子稍微復(fù)雜了下,考慮了全部相同導(dǎo)致 num++ 的情況,另,優(yōu)化了代碼

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 中的數(shù)據(jù)逐步加給 listTemp,作為函數(shù)返回值;
        // 注意這里 listTemp 反復(fù)迭代,但始終指向的是保存在內(nèi)存里的同一個(gè)對(duì)象,一直在修改 listTemp 的數(shù)據(jù);
        listTemp = listTemp === undefined ? JSON.parse(JSON.stringify(listA)) : listTemp;
        listB.forEach((objB, indexB) => {

            //求出當(dāng)前 level 中, listB 中項(xiàng)在 listA 中的索引,不存在,則返回 -1

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

            //如果當(dāng)前 level 中,listA 中 沒有 listB  的 id,把 listB 這個(gè)level的數(shù)據(jù)拷給 listTemp

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

                //如果有,判斷是否到最后一層
                //不是最后一層,切換到下一層 level,繼續(xù)    
                //是最后一層,listTemp 當(dāng)前層 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;
}
2018年2月17日 12:46