前端面试通常都会问到数组去重的问题。
方法一
思路:
1,定义一个新数组用于存放结果;
2,遍历要去重的数组,把遍历的那个元素去新数组里比对,如果有相同的,忽略,没有,则存放到新数组里。
代码:
const unique = (arr)=>{
let res = [];
arr.forEach((v,i)=>{
if(res.indexOf(v) == -1){
res.push(v);
}
});
return res;
}
let testArr = [1,1,'2',2,3,4,'3'];
console.log(unique(testArr));
优点:适合不同数据类型;
缺点:两次遍历,效率不高。indexOf去查找索引也是需要遍历的。
方法二
思路:利用对象key的唯一性。
1,定义一个新数组用于存放结果,定义一个空对象存放数组遍历的值。
2,遍历数组,把每个元素去和对象对比,如果对象里有这个属性,则说明已经存在了,就忽略,如果对象里没有,就push到结果数组中,同时在对象上添加以这个元素为key的属性,值设置为true。
代码:
const unique = (arr)=>{
let res = [];
let temp = {};
arr.forEach((v,i)=>{
if(!temp[v]){
res.push(v);
temp[v] = true;
}
});
return res;
}
let testArr = [1,1,'2',2,3,4,'3'];
console.log(unique(testArr));
优点:一次遍历,效率稍好。
缺点:对数据类型不友好。数字1和字符串‘1’会被当做相同的元素。
方法三
思路:考虑一下不同的基本类型。对方法二进行修改,加上类型。
代码:
const unique = (arr)=>{
let res = [];
let temp = {};
arr.forEach((v,i)=>{
let key = typeof v + v;
if(!temp[key]){
res.push(v);
temp[key] = true;
}
});
return res;
}
let testArr = [1,1,'2',2,3,4,'3',undefined,undefined,null,true,false,true];
console.log(unique(testArr));
优点:一次遍历,效率稍好,支持基本数据类型。
缺点:对对象类型不友好。
方法四
思路:先排序,后比较。
1,利用数组自带排序,内部实现有快排。排序后,相同的元素在一起,用遍历的元素去和结果数组里的最后一个元素比较,不同则添加到结果里,相同则说明结果里已经存在此相同元素,忽略掉它。
代码:
const unique = (arr)=>{
arr.sort();
let res = [];
for(let i=1;i<arr.length;i++){
if(arr[i] !== res[res.length-1]){
res.push(arr[i]);
}
};
return res;
}
let testArr = [1,1,'2',2,3,4,'3'];
console.log(unique(testArr));
此方法比第一种两次遍历的快,比hash慢,占用内存少,时间空间均衡。
优点:性能均衡。
缺点:会改变原数组的顺序。
方法五
思路:利用ES6的Set。
代码:
const unique = (arr)=>{
return Array.from(new Set(arr));
// 或者 return [...new Set(arr)]
}
let testArr = [1,1,'2',2,3,4,'3'];
console.log(unique(testArr));
优点:666
缺点:太拉风
暂时写这几种,还有其他方法。但实际应用还是要根据具体的实际场景来做对应的处理。
好久没有更新了。
转载请注明带链来源:春语精椿