这两天在开发需求的过程中,需要处理一个数组数据,对相邻元素的具有相同的点合并元素里面的数组。
我们先看一下处理的数组是什么样的。
let array = [
{
name: '数据来源1',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '13',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '14',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源3',
list: [
{
dataCode: '15',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}]
我们再看一下处理后的数组是什么样的。
let array = [
{
name: '数据来源1',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '13',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '14',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源3',
list: [
{
dataCode: '15',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}]
数组中两个数据来源2中的list合并到一块,并且删除了第二个数据来源2。
当然这只是用简单的数据演示了一下,事实上数据中有好几个相邻的元素的name值都相同,所以这就需要我们封装一个健壮的函数来满足需求。
尝试了好几种方法,最后找到了一种简单的方法,方法如下:
function mergeAdjacentItem(arr, type, mergeParam) {
return arr.reduce((result, cur, index, value) => {
if (index == 0 || cur[type] != result[result.length - 1][type]) {
result.push(cur)
} else {
result[result.length - 1][mergeParam].push(cur[mergeParam])
}
return result;
}, []);
}
这个方法中的关键点,首先在于对reduce方法的理解,其次是需要对每次循环的数组元素做处理,然后再添加到result中。
关于reduce方法,可以看一下这篇文章:JavaScript中的reduce()的理解和示例说明
我们来看一下封装的函数的效果:
let array = [
{
name: '数据来源1',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '13',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '14',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '15',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源2',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '16',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源1',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '17',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源3',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}, {
name: '数据来源3',
list: [
{
dataCode: '12',
dataName: '照片',
dataSort: 20,
fileList: []
},
{
dataCode: '18',
dataName: '照片',
dataSort: 20,
fileList: []
}
]
}]
function mergeAdjacentItem(arr, type, mergeParam) {
return arr.reduce((result, cur, index, value) => {
if (index == 0 || cur[type] != result[result.length - 1][type]) {
result.push(cur)
} else {
result[result.length - 1][mergeParam].push(cur[mergeParam])
}
return result;
}, []);
}
let array2 = mergeAdjacentItem(array, 'name', 'list')
console.log('----------------array2----------')
console.log(array2);
最后array2打印的效果如下:
我这边随后又进行了延伸,
1、比如:[1,2,2,2,3,3,4,5,5,6,6]经过处理之后变成[1,2,3,4,5,6]
这个如果用reduce去实现的话,代码如下:
function mergeAdjacentItem(arr){
return arr.reduce((result,cur,index,value)=>{
if(index == 0 || cur !== arr[index+1]){
result.push(cur)
}
return result
},[])
}
let arr = [1,2,2,2,3,3,4,5,5,6,6];
let arr2 = mergeAdjacentItem(arr);
arr2 // [1,2,3,4,5,6]
2、比如:[1,2,2,2,3,3,4,5,5,6,6] 经过处理之后变成 [1,[2,2,2],[3,3],4,[5,5],[6,6]]
这个如果用reduce去实现的话,代码如下:
function mergeAdjacentItem(arr){
return arr.reduce((result,cur,index,value)=>{
if(index == 0 || (cur != arr[index+1]&&Object.prototype.toString.call(result[result.length - 1]) == '[object Array]'&&result[result.length - 1][0] != cur)){
result.push(cur)
}else{
if(Object.prototype.toString.call(result[result.length - 1]) == '[object Array]'){
}else{
}
}
},[])
}