数组常用方法,早中晚你会用到

1,293 阅读4分钟

在这里,将数组常用的几个方法进行总结,便于后续复习及提高日常的开发效率

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'))

image.png

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'))

image.png

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'))

image.png

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'))

image.png

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))

image.png

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) // 改变原数组

image.png

8、结尾

以上几种关于数组的方法都是工作中常用的,若这篇文章对你有收获,留下你的小心心吧,😁😁