如何通过 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]))
我想通过 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:
你可以使用递归:
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]))