在前端的面试或笔试中,经常会碰到让你写一段数组去重的代码,今天就带大家一起来学习数组去重的 6 个方法,所谓人无我有,人有我优。当别人掌握了一两种方法时,你就要努力掌握比别人更多的方法,这样就可以让自己更有竞争力些。

直接遍历法

这种方法直接遍历数组,利用 JavaScript 的 indexOf 方法,新建一个新数组,用这个数组去判断旧数组中的每一个数是否等于-1,如果是,说明该数在新数组中不存在,则将其添加进新数组,遍历完后就能将数组去重并保存至新建的数组中。这里要解释一下Array.prototype.indexOf()方法,mozilla 给出该方法的作用是The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.了解了它的含义后就可以开始写以下的函数:

1
2
3
4
5
6
7
8
9
10
11
12
function oSort1(arr){
var newArr = [];
for(var i=0;i<arr.length;i++){
if(newArr.indexOf(arr[i]) === -1){
newArr.push(arr[i]);
}
}
return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort1(arr)); // 1, 5, 9, null, undefined

reduce 函数

使用数组的 reduce 方法在结合 indexOf 两个方法同样能去重。mozilla 官方对 reduce 的解释是 arr.reduce(callback[, initialValue]) 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。简单点讲就是对数组中的每一个数作用一个函数,这个回调函数就是第一个参数 callback ,第二个参数是传入的初始值,不传则使用数组中的第一个元素,注意在没有初始值的空数组上调用 reduce 将报错。

1
2
3
4
5
6
7
8
9
10
11
function oSort2(arr){
return arr.reduce(function(prev,next){
if(prev.indexOf(next) === -1){
prev.push(next);
}
return prev;
}, []);
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort2(arr)); // 1, 5, 9, null, undefined

相邻比较

这种方法利用数组的 sort() 函数,这个函数原本是对数组进行排序的,但在这里我们不用它进行排序,而只是让它将重复的元素聚拢起来,接着我们比较相邻的两个数,如果相等,则跳过;如果不相等,我们就将其添加进新数组里,这样得到的数组就是去重后的数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
function oSort3(arr){
var newArr = [arr[0]];
arr.sort();
for(var i=1;i<arr.length;i++){
if(arr[i] !== arr[i-1]){
newArr.push(arr[i]);
}
}
return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort3(arr)); // 1, 5, 9, null, undefined

这里为了简便,直接将第一个元素添加进新数组,然后循环 i 从 1 开始,也就是从第二个数开始遍历直到结束。

下标指针遍历

第四种方法是利用数组的下标指针,来确定是否是相同的元素,如果是的话,就让其指针递增跳过,然后不断把不重复的数组保存至新数组中。来看如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function oSort4(){
var newArr = [];
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i] === arr[j]){
j = ++i;
}
}
newArr.push(arr[i]);
}
return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort4(arr)); // 1, 9, null, 5, undefined

上面的代码嵌套了两层循环,分别有 i 和 j 两指针,其中 j 总是比 i 大 1,通过判断数组中这个数与它后面的数是否相等,如果相等,则说明这个数重复了,我们便将指针 i 和 j 继续往后运行,然后用 j = ++i 保持 j 比 i 大 1。最后一直把不重复的指针 i 对应的元素添加进数组。

临时对象存储

借用一个临时对象来存储数组元素,判断数组中的元素是否在对象中,如果不存在,就将该数添加进数组,并在临时对象中做标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function oSort5(arr){
var newArr = [];
var temp = {};
for(var i=0;i<arr.length;i++){
if(!temp[arr[i]]){
newArr.push(arr[i]);
temp[arr[i]] = true;
}
}
return newArr;
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort5(arr)); // 1, 5, 9, null, undefined

简单粗暴法

这种方法厉害了,只需要一句代码:

1
2
3
4
5
6
function oSort6(arr){
return Array.from(new Set(arr));
}

var arr = [1,1,5,9,null,5,undefined,undefined];
console.log(oSort6(arr)); // 1, 5, 9, null, undefined

利用 ES6 中的 Set 集合里元素唯一的特性,先将数组转换为集合,这样里面的元素就是唯一的了,再用 Array.from 方法将集合转回数组返回,是不是很方便有木有?附上 Array.from 方法的官方介绍: 从一个类似数组或可迭代对象中创建一个新的数组实例.
以上就是 6 种数组去重的方法啦,如果您有什么意见或建议,欢迎一起学习交流!