如何通过 JavaScript/Lodash 中的重复键深度合并两个集合?

How to deep merge two collections by duplicate key in JavaScript/Lodash?

我想通过 javascript 中的重复键合并两个集合,这里是示例集合:

let collection1 = [
    {
        title: 'Overview',
        key: 'Test-overview',
        isLeaf: true
    },
    {
        title: 'Folder 1',
        key: 'Test-Folder_1',
        children: [
            {
                title: 'Folder 1 Content 1',
                key: 'Test-Folder_1-Content_1',
                isLeaf: true,
            },
        ],
    }
]


let collection2 = [
        {
            title: 'Folder 1',
            key: 'Test-Folder_1',
            children: [
                {
                    title: 'Sub Folder 1 in Folder 1',
                    key: 'Test-Folder_1-Sub_Folder_1',
                    children: [
                        {
                            title: 'Sub Folder 1 Conetent',
                            key: 'Test-Folder_1-Sub_Folder_1-Content',
                            isLeaf: true,
                        },
                    ],
                },
            ],
        }
    ]

这是示例输出:

let exampleOutput = [
        {
            title: 'Overview',
            key: 'Test-overview',
            isLeaf: true
        },
        {
            title: 'Folder 1',
            key: 'Test-Folder_1',
            children: [
                {
                    title: 'Folder 1 Content 1',
                    key: 'Test-Folder_1-Content_1',
                    isLeaf: true,
                },
                {
                    title: 'Sub Folder 1 in Folder 1',
                    key: 'Test-Folder_1-Sub_Folder_1',
                    children: [
                        {
                            title: 'Sub Folder 1 Conetent',
                            key: 'Test-Folder_1-Sub_Folder_1-Content',
                            isLeaf: true,
                        },
                    ],
                },
            ],
        }
    ]

如何使用 Javascript 实现此输出?我尝试使用 Lodash _.merge 和 _.mergeWith,但输出不是我想要的。 我也试过这个 link: @BenG 的回答,但它只能合并集合的第一层,这意味着如果我有 collection3 包含 Test-Folder_1-Sub_Folder_1 中的另一个内容,它将替换为新集合的第一层。

你可以使用递归:

let collection1 = [{title: 'Overview', key: 'Test-overview', isLeaf: true}, {title: 'Folder 1', key: 'Test-Folder_1', children: [{title: 'Folder 1 Content 1', key: 'Test-Folder_1-Content_1', isLeaf: true, },],}]
let collection2 = [{title: 'Folder 1', key: 'Test-Folder_1', children: [{title: 'Sub Folder 1 in Folder 1', key: 'Test-Folder_1-Sub_Folder_1', children: [{title: 'Sub Folder 1 Conetent', key: 'Test-Folder_1-Sub_Folder_1-Content', isLeaf: true,},],},],}]
function merge(collections){
   var formed = {}
   for (var i of collections){
      key = JSON.stringify(Object.keys(i).filter(x => x != 'children').map(x => [x, i[x]]))
      if (!(key in formed)){ 
         formed[key] = []
      }
      formed[key] = [...formed[key], ...('children' in i ? i.children : [])]
   }
   return Object.keys(formed).map(x => ({...Object.fromEntries(JSON.parse(x)), ...(formed[x].length ? {'children':merge(formed[x])} : {})}))
}
console.log(merge([...collection1, ...collection2]))