数组深度合并
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" } ] } ] } ]
/** * @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 }
<!-- * @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>