js - Array - arrayDeepMerge
js - Array - arrayDeepMerge
需求
数组深度合并
var arr1 = [
{
name: '正卷',
id: '1',
Children: [
{
name: '目录1',
id: '1-1',
Children: [
{
name: '第1页',
id: '1-1-1'
},
{
name: '第2页',
id: '1-1-2'
},
{
name: '第3页',
id: '1-1-3'
}
]
},
{
name: '目录2',
id: '1-2',
Children: [
{
name: '第1页',
id: '1-2-1'
},
{
name: '第2页',
id: '1-2-2'
},
{
name: '第3页',
id: '1-2-3'
}
]
}
]
}
]
var arr2 = [
{
name: '正卷',
id: '1',
Children: [
{
name: '123',
id: '1-1',
Children: [
{
name: '第1页',
id: '1-1-1'
},
{
name: '第2页',
id: '1-1-2'
},
{
name: '第4页',
id: '1-1-4'
}
]
}
]
},
{
name: '副卷',
id: '2',
Children: [
{
name: '123',
id: '2-1',
Children: [
{
name: '第1页',
id: '2-1-1'
},
{
name: '第2页',
id: '2-1-2'
},
{
name: '第3页',
id: '2-1-3'
}
]
}
]
}
]
期望结果
[
{
"name": "正卷",
"id": "1",
"Children": [
{
"name": "123",
"id": "1-1",
"Children": [
{
"name": "第1页",
"id": "1-1-1"
},
{
"name": "第2页",
"id": "1-1-2"
},
{
"name": "第3页",
"id": "1-1-3"
},
{
"name": "第4页",
"id": "1-1-4"
}
]
},
{
"name": "目录2",
"id": "1-2",
"Children": [
{
"name": "第1页",
"id": "1-2-1"
},
{
"name": "第2页",
"id": "1-2-2"
},
{
"name": "第3页",
"id": "1-2-3"
}
]
}
]
},
{
"name": "副卷",
"id": "2",
"Children": [
{
"name": "123",
"id": "2-1",
"Children": [
{
"name": "第1页",
"id": "2-1-1"
},
{
"name": "第2页",
"id": "2-1-2"
},
{
"name": "第3页",
"id": "2-1-3"
}
]
}
]
}
]
utils
/**
* @method 数组深度合并
* @description 数组深度合并
* @param arr1
* @param arr2
* @param key 判断相同字段 默认id
* @param childsKey 子数组字段 默认childs
* @return
*/
function arrayDeepMerge(arr1, arr2, key = 'id', childsKey = 'childs') {
let resArray = [],
concatArray = arr1.concat(arr2)
concatArray.forEach(v => {
// resArray 中不存在此key 表示未合并,进行合并
if (!resArray.some(v1 => v1[key] == v[key])) {
let targetObjs = concatArray.filter(v1 => v1[key] == v[key])
if (targetObjs.length == 1) {
// 此key在arr1,arr1不冲突,不需要merge,push即可
resArray.push(v)
} else {
// 此key在arr1,arr1冲突,需要merge
let [obj1, obj2] = targetObjs
resArray.push(
Object.assign(
{},
obj1,
obj2,
// 存在子数组 递归子数组合并
obj1[childsKey]?.length || obj2[childsKey]?.length
? {
[childsKey]: arrayDeepMerge(obj1[childsKey] || [], obj2[childsKey] || [], key, childsKey)
}
: {}
)
)
}
}
// resArray 中存在此key 表示已合并,不需要操作
})
return resArray
}
demo
<!--
* @createDate: 2022-07-23 15:17:11
* @Author: zclee
* @LastEditTime: 2022-07-23 16:13:27
* @LastEditors: zclee
* @FilePath: \lee-vue-press\cnblog\js - Array - arrayDeepMerge.html
* @Description:
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
var arr1 = [
{
name: '正卷',
id: '1',
Children: [
{
name: '目录1',
id: '1-1',
Children: [
{
name: '第1页',
id: '1-1-1'
},
{
name: '第2页',
id: '1-1-2'
},
{
name: '第3页',
id: '1-1-3'
}
]
},
{
name: '目录2',
id: '1-2',
Children: [
{
name: '第1页',
id: '1-2-1'
},
{
name: '第2页',
id: '1-2-2'
},
{
name: '第3页',
id: '1-2-3'
}
]
}
]
}
]
var arr2 = [
{
name: '正卷',
id: '1',
Children: [
{
name: '123',
id: '1-1',
Children: [
{
name: '第1页',
id: '1-1-1'
},
{
name: '第2页',
id: '1-1-2'
},
{
name: '第4页',
id: '1-1-4'
}
]
}
]
},
{
name: '副卷',
id: '2',
Children: [
{
name: '123',
id: '2-1',
Children: [
{
name: '第1页',
id: '2-1-1'
},
{
name: '第2页',
id: '2-1-2'
},
{
name: '第3页',
id: '2-1-3'
}
]
}
]
}
]
/**
* @method 数组深度合并
* @description 数组深度合并
* @param arr1
* @param arr2
* @param key 判断相同字段 默认id
* @param childsKey 子数组字段 默认childs
* @return
*/
function arrayDeepMerge(arr1, arr2, key = 'id', childsKey = 'childs') {
let resArray = [],
concatArray = arr1.concat(arr2)
concatArray.forEach(v => {
// resArray 中不存在此key 表示未合并,进行合并
if (!resArray.some(v1 => v1[key] == v[key])) {
let targetObjs = concatArray.filter(v1 => v1[key] == v[key])
if (targetObjs.length == 1) {
// 此key在arr1,arr1不冲突,不需要merge,push即可
resArray.push(v)
} else {
// 此key在arr1,arr1冲突,需要merge
let [obj1, obj2] = targetObjs
resArray.push(
Object.assign(
{},
obj1,
obj2,
// 存在子数组 递归子数组合并
obj1[childsKey]?.length || obj2[childsKey]?.length
? {
[childsKey]: arrayDeepMerge(obj1[childsKey] || [], obj2[childsKey] || [], key, childsKey)
}
: {}
)
)
}
}
// resArray 中存在此key 表示已合并,不需要操作
})
return resArray
}
let res = arrayDeepMerge(arr1, arr2, 'id', 'Children')
console.log(JSON.stringify(res, null, 2))
// console.log(res)
</script>
</body>
</html>
Lee2