数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码 在真实的项目中碰到的数组去重,一般都是后台去处理,很少让前端处理数组去重。虽然日常项目用到的概率比较低,但还是需要了解一下,以防面试的时候可能回被问到。
【1】利用ES6 Set去重(ES6中最常用)性能也可以
function unique (arr) {
return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
使用 Set 又需要多久时间来处理 15W 的数据呢?
然后我在两个数组长度后面分别加了一个 0,在 150W 的数据量之下…
居然有如此高性能且简洁的数组去重办法?!
【2】for…of + Object
这个方法我只在一些文章里见过,实际工作中倒没怎么用
首先创建一个空对象,然后用 for 循环遍历
利用对象的属性不会重复这一特性,校验数组元素是否重复
function distinct(arr) {
let result = []
let obj = {}
for (let i of arr) {
if (!obj[i]) {
result.push(i)
obj[i] = 1 //这里1只是为了obj的值为1 不一定只是1可以为任何值
}
}
return result
}
当我看到这个方法的处理时长,我又傻眼了
15W 的数据居然只要 16ms ??? 比 Set () 还快???
然后我又试了试 150W 的数据量…
【3】双重 for 循环
最容易理解的方法,外层循环遍历元素,内层循环检查是否重复
当有重复值的时候,可以使用 push (),也可以使用 splice ()
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}] //NaN和{}没有去重,两个null直接消失了
【4】Array.prototype.indexOf()
基本思路:如果索引不是第一个索引,说明是重复值。
实现一:
- 利用Array.prototype.filter()过滤功能
- Array.prototype.indexOf()返回的是第一个索引值
- 只将数组中元素第一次出现的返回
- 之后出现的将被过滤掉
实现二:Array.prototype.unique = function () {
return this.filter((item, index) => {
return this.indexOf(item) === index;
})
}
复制代码
let arr = [1, 2, 3, 22, 233, 22, 2, 233, 'a', 3, 'b', 'a'];
Array.prototype.unique = function () {
const newArray = [];
this.forEach(item => {
if (newArray.indexOf(item) === -1) {
newArray.push(item);
}
});
return newArray;
}