在平时敲代码时,经常会遇到需要对数组进行去重的情况,若两个数组较小,此时使用任何一种去重方式都不会对效率产生太大影响,但当数组较大时,好的去重方法会明显提高运行效率。
此外,去重方法也经常出现在各类面试笔试题中,为此我总结了一下各种去重方法,供大家参考。
这种方法是最直观最容易想到的了,代码如下:
let arr = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i].id === arr[j].id) {
arr.splice(j, 1)
j--
}
}
}
console.log('arr--', arr)
实现起来简单直观,但代码量大且效率低下,不够优雅。
利用findIndex 查找元素,根据返回结果组建最终结果数组,这样就优雅多了。
let arr1 = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
let newArr1 = []
arr1.forEach((item, index) => {
arr1.findIndex(el => el.id == item.id) == index && newArr1.push(item)
})
console.log('newArr1', newArr1)
findIndex作用:找到遍历的数组中的第一个符合判断条件
的值,并返回该值对应的索引。
代码解析:
forEach+findindex方法的变种,代码如下:
let arr2 = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
arr2 = arr2.filter((item, index) => {
return arr2.findIndex(el => el.id == item.id) == index
})
console.log('arr3--', arr2)
这种方式,和forEach+findindex方式原理相同,我就不解释了。
针对的是由基本数据类型组成的数组,我们只要遍历一层,搭配indexOf、includes等方法,就可以实现去重,代码如下:
let arr = [ 1, 1, 1, "1", "lsm", "52", 2, 81, 2, 81]
let newArr = []
arr.map((item, index) => {
//!newArr.includes(item) && newArr.push(item)
newArr.indexOf(arr1[i]) === -1 && newArr.push(arr1[i])
})
console.log('newArr--', newArr)
如果数组内是引用类型的参数,在indexOf、includes无法使用时,可以使用some作为替代,上代码:
let arr3 = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
let newArr3 = []
arr3.forEach((item, index) => {
!newArr3.some(el => el.id == item.id) && newArr3push(item)
})
console.log('newArr2', newArr2)
some作用:判断数组中是否存在满足条件的值,如果有则返回true,完整遍历不会终止循环,可以使用return自行终止(此例中并没用到该特性)
此方法仍然为filter+findIndex的变种,使用find替代findIndex,代码如下:
let arr4 = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
arr4 = arr4.filter(item => {
return arr4.find(el => el.id == item.id) == item
})
console.log('arr4', arr4)
find返回的是符合条件的遍历项,需要注意的是,这里不推荐使用find,因为find方法比较的是引用地址,如果数组中的对象地址出现相同的情况则达不到去重效果,如:
let obj = {id: 10, name: 'lsm'}
let arr = []
arr.push(obj)
arr.push(obj)
//arr中的两个对象引用地址实际上是一样
//Set不能对对象去重,但是这种情况可以
find作用:找出符合判断条件的第一项,并进行返回
最终总结:
let arr5 = [
{id: 1, name: 'lsm'},
{id: 2, name: 'mjl'},
{id: 1, name: 'lsm'}
]
let newArr5 = []
arr5.map((item, index) => {
// !newArr5.some(el => el.id == item.id) && newArr5.push(item)
// arr5.findIndex(el => el.id === item.id) === index && newArr5.push(item)
arr5.find(el => el.id === item.id) === item && newArr5.push(item)
})
console.log('arr5', newArr5)
作者简介 :游逸,高级软件工程师,7年开发经验,喜欢分享干货与关注技术前沿,欢迎一起交流学习