数组去重属于面试高频考点,查阅过很多的博客,看过厉害的博主甚至列出过12钟数组去重方法,但是并没有对数组去重的过程给出一个具体的解释,这对于新人来说并不友好,今天,就由我来帮助大家打开新世界的大门吧。
1.ES6去重
function unique(arr) {
return Array.from(new Set(arr));
}
function unique(arr) {
return [...new Set(arr)];
}
复制代码
思路: 利用的是ES6中Set数据结构,Set是ES6中新增的集合数据结构,类似于数组但是成员的值都只能是唯一的,上述去重利用的正是这一特性。
优点:代码最少。
缺点:要考虑兼容性,无法去除{}对象
2.双重循环去重
function unique(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
}
复制代码
思路: 双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个元素。
优点:好理解
缺点:时间复杂度为O(n^2),效率低
3.利用indexOf去重
function unique(arr) {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
复制代码
思路:新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。
优缺点和上一个类似。
4.filter去重
function unique(arr) {
return arr.filter((temp, index) => arr.indexOf(temp) === index);
}
复制代码
思路: 与上面的indexOf去重类似。
优点: 代码比较少。
缺点:有点难理解。
5.reduce去重
function unique(arr) {
return arr.reduce((pre, cur) => (pre.includes(cur) ? pre : [...pre, cur]),[]);
}
复制代码
思路: 利用reduce前后遍历元素的特点,刚开始借助一个空数组开始,遍历时判断后面的元素是否在之前的数组中已经出现,如果是,返回之前的数组,否则将新元素添加进数组中。
优点: 代码比较少。
缺点:有点难理解。
6.利用map去重
function unique(arr) {
let map = new Map();
let newArr = [];
for (let i = 0; i < arr.length; i++) {
if (map.has(arr[i])) {
map.set(arr[i], true);
} else {
map.set(arr[i], false);
newArr.push(arr[i]);
}
}
return newArr;
}
复制代码
Map与Object很像,不同的是Object的key只能是字符串,而Map的key可以是任意数据类型。
思路: 创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果
优点: 这种去重还可以拓展到别的题目上,比如,重复出现的原型有哪些,分别出现了几次。
缺点: 感觉没啥缺点,就是好像也不能去除{}重复。
7.利用hasOwnProperty
function unique(arr) {
let obj = {};
return arr.filter(function(item, index, arr){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
复制代码
思路: 利用hasOwnProperty 判断是否存在对象属性
优点: 可以去掉”{}”
缺点: 很难理解
后续我也会写关于ES6语法的博客,请大家多多关注哦。
谢谢大家看到这里。