在这里,将数组常用的几个方法进行总结,便于后续复习及提高日常的开发效率
1、数组归档(通过某一字段对数组对象进行分组)
这篇文章 juejin.cn/post/700408… 中有相关方法的介绍,掘友也给出了新的方法,选择自己容易理解的总结经验吧
2、数组去重
之前写过一篇文章是关于数组去重,但只是对于简单数据类型的数组起作用。若只是简单数据类型的数组去重可以看看这几种方法:
juejin.cn/post/698626…
这里将介绍一个兼容的处理方式(数组对象 & 基本数据类型都适用)
const objArr = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 1,
userName: '张海洋'
}, {
userId: 4,
userName: '李好'
}, {
userId: 2,
userName: '王小晓'
}]
const numberArr = [1, 3, 1, 5, 3, 2, 1, 5, 2, 4];
/**
*
* @desc 数组去重arrRmDuplicates(arr, key)
* @param {Array} arr:需要去重的数组
* @param {String} key:去重关键字
* @return {Array} 返回一个数组
*/
function arrRmDuplicates(arr, key) {
let obj = {};
return arr.reduce((newArr, item) => (key ? (obj[item[key]] ? '' : obj[item[key]] = 1 && newArr.push(item)) : newArr = Array.from(new Set(arr)), newArr), [])
}
console.log(arrRmDuplicates(numberArr))
console.log(arrRmDuplicates(objArr, 'userId'))
3、数组并集
const num_1 = [1, 2, 3, 4, 5]
const num_2 = [2, 3, 4, 5, 6,8,10]
const objArr_1 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 3,
userName: '李天霸'
}, {
userId: 4,
userName: '李好'
}]
const objArr_2 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 6,
userName: '吴小飞'
}, {
userId: 8,
userName: '唐三'
}]
/**
*
* @desc 数组并集arrUnio(arr_1,arr_2, key)
* @param {Array,Array} arr_1,arr_2:原数组
* @param {String} key:关键字
* @return {Array} 返回一个数组
*/
function arrUnio(arr_1, arr_2, key) {
return arr_1.concat(arr_2.filter(item => key ? !arr_1.map(it=>it[key]).includes(item[key]) : !arr_1.includes(item)))
}
console.log(arrUnio(num_1, num_2))
console.log(arrUnio(objArr_1, objArr_2, 'userId'))
4、数组交集
const num_1 = [1, 2, 3, 4, 5]
const num_2 = [2, 3, 4, 5, 6, 8, 10]
const objArr_1 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 3,
userName: '李天霸'
}, {
userId: 4,
userName: '李好'
}]
const objArr_2 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 6,
userName: '吴小飞'
}, {
userId: 8,
userName: '唐三'
}]
/**
*
* @desc 数组交集arrIntersection(arr_1,arr_2, key)
* @param {Array,Array} arr_1,arr_2:原数组
* @param {String} key:关键字
* @return {Array} 返回一个数组
*/
function arrIntersection(arr_1, arr_2, key) {
return arr_1.filter(item => key ? arr_2.map(it => it[key]).includes(item[key]) : arr_2.includes(item))
}
console.log(arrIntersection(num_1, num_2))
console.log(arrIntersection(objArr_1, objArr_2, 'userId'))
5、数组差集
const num_1 = [1, 2, 3, 4, 5]
const num_2 = [2, 3, 4, 5, 6, 8, 10]
const objArr_1 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 3,
userName: '李天霸'
}, {
userId: 4,
userName: '李好'
}]
const objArr_2 = [{
userId: 1,
userName: '张海洋'
}, {
userId: 2,
userName: '王小晓'
}, {
userId: 6,
userName: '吴小飞'
}, {
userId: 8,
userName: '唐三'
}]
/**
*
* @desc 数组差集arrDifference(arr_1,arr_2, key)
* @param {Array,Array} arr_1,arr_2:原数组
* @param {String} key:关键字
* @return {Array} 返回一个数组
*/
function arrDifference(arr_1, arr_2, key) {
let duplicatesArr = arrRmDuplicates([...arr_1, ...arr_2], key) // arrRmDuplicates是前面提到的数组去重方法
return duplicatesArr.filter(item => (![arr_1, arr_2].every(it => key ? (it.map(its => its[key]).includes(item[key])) : it.includes(item))))
}
console.log(arrDifference(num_1, num_2))
console.log(arrDifference(objArr_1, objArr_2, 'userId'))
6、数组扁平化
『方法一』: 封装递归函数
const arr = [1, 2, [3, 4], 5, [6, [7, [8, 9]]]]
const objArr = [{
userId: 1,
userName: '张海洋'
}, [{
userId: 2,
userName: '王小晓'
}, [{
userId: 3,
userName: '李斯'
}]], {
userId: 6,
userName: '吴小飞'
}, {
userId: 8,
userName: '唐三'
}]
/**
*
* @desc 数组扁平化arrFlat(arr, i)
* @param {Array} arr:原数组
* @param {Number} i:想要拉平的层数,默认为1
* @return {Array} 返回一个数组
*/
function arrFlat(arr, i = 1) {
return arr.reduce((newArr, item) => newArr.concat((i>1&&Array.isArray(item))?arrFlat(item,i-1):item), [])
}
console.log(arrFlat(arr))
console.log(arrFlat(arr,2))
console.log(arrFlat(objArr, 1))
/* -------------------- */
『方法二』: ES6新增的`Array.prototype.flat()`用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
console.log(arr.flat())
console.log(arr.flat(2))
console.log(objArr.flat(1))
7、数组中两个元素值交换
const arr = [1, 2, 3, 4, 5, 6]
/**
*
* @desc 数组值交换arrExchange(arr, index_1, index_2)
* @param {Array} arr:原数组
* @param {Number} index_1:第一个交换值的索引
* @param {Number} index_2:第二个交换值的索引
* @return {Array} 返回一个数组
*/
function arrExchange(arr, index_1, index_2) {
arr.splice(index_1, 1, arr.splice(index_2, 1, arr[index_1])[0])
return arr
}
console.log(arrExchange(arr, 1, 3))
上面这个方法会改变原数组,若不想改变原数组,可以考虑加个开关进行控制,达到兼容的效果,方法如下:
const arr = [1, 2, 3, 4, 5, 6]
/**
*
* @desc 数组值交换arrExchange(arr, index_1, index_2,isChangeSourceArr=false)
* @param {Array} arr:原数组
* @param {Number} index_1:第一个交换值的索引
* @param {Number} index_2:第二个交换值的索引
* @param {Boolean} isChangeSourceArr:是否改变原数组,默认不改变
* @return {Array} 返回一个数组
*/
function arrExchange(arr, index_1, index_2, isChangeSourceArr = false) {
let newArr = isChangeSourceArr ? arr : JSON.parse(JSON.stringify(arr)); // 这里的深拷贝不适用于数组元素为函数及Symbol数据类型等
newArr.splice(index_1, 1, newArr.splice(index_2, 1, newArr[index_1])[0])
return newArr
}
console.log(arrExchange(arr, 1, 3),arr) // 不改变原数组
console.log(arrExchange(arr, 1, 3,true),arr) // 改变原数组
8、结尾
以上几种关于数组的方法都是工作中常用的,若这篇文章对你有收获,留下你的小心心吧,😁😁