1.最基本的去重方法
思路:定义一个新数组,并存放原数组的第一个元素,然后将元素组一一和新数组的元素对比,若不同则存放在新数组中。
function unique(arr){
var repeat=false;
var res = [arr[0]];
for(var i=1;i<arr.length;i++){
var repeat = false;
for(var j=0;j<res.length;j++){
if(arr[i] === res[j]){
repeat = true;break;
}
}
if(!repeat){
res.push(arr[i]);
}
}
return res;
}
2.先排序在去重
思路:先将原数组排序,在与相邻的进行比较,如果不同则存入新数组
function unique(arr){
var arr2 = arr.sort();
var res = [arr2[0]];
for(var i=1;i<arr2.length;i++){
if(arr2[i] !== res[res.length-1]){
res.push(arr2[i]);
}
}
return res;
}
这个方法不推荐:比如
var arr=[1,'1',2,1,3,4,1];
var arr2=arr.sort();
console.log(arr2);//[1, "1", 1, 1, 2, 3, 4]
unique(arr);//[1,"1",1,2,3,4]
3.利用reduce去重(推荐)
arr.reduce(callback,[initialValue])
callback (执行数组中每个值的函数,包含四个参数)
- prev (第一次的prev的值是数组的第一个值或者是提供的初始值(initialValue),上一次调用回调返回的值)
- curr (prev设置初始值的化,curr就为数组第一个值,否则为第二个值。数组中当前被处理的元素)
- index (当前元素在数组中的索引)
- array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
//初始化prev为[],curr为1
newArr4 = arr4.reduce((prev, curr) => prev.includes(curr)? prev : [...prev,curr],[])
4.利用对象的属性去重(推荐)
思路:每次取出原数组的元素,然后在对象中访问这个属性,如果存在就说明重复
function unique(arr){
var res =[];
var json = {};
for(var i=0;i<arr.length;i++){
if(!json[arr[i]]){
res.push(arr[i]);
json[arr[i]]={};
json[arr[i]].key=arr[i];
}
}
return res;
}
这个方法不推荐使用:比如
var arr=[1,'1',2,3];
unique(arr);// [1, 2, 3]
5.利用indexOf或includes查询
function unique(arr){
var newArr = [arr[0]];
for(var i=1;i<arr.length;i++){
if(newArr.indexOf(arr[i]) == -1){
newArr.push(arr[i]);
}
}
return newArr;
}
使用es6 数组includes()方法
let newArr2 = []
for (let i = 0; i < arr.length; i++) {
if (!newArr2.includes(arr[i])) {
newArr2.push(arr[i])
}
}
console.log(newArr2);
indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。
6.es6的Set与Array.from() (最简洁)
set是一种新的数据结构,它可以接收一个数组或者是类数组对象,自动去重其中的重复项目,set返回的是一个对象。
Array.from()的作用,可以把伪类数组对象,可迭代对象转化为数组。
var arr=[1,2,1,'1',null,null,undefined,undefined,NaN,NaN]
let res=Array.from(new Set(arr));//{1,2,"1",null,undefined,NaN}
//or
let newarr=[...new Set(arr)]