用一杯咖啡的时间,来聊一聊数组去重的方法
前言
数组去重是非常经典的面试题目。十次面试,能碰到十一次(这里带有夸张的成分)。这里之所以来讲一下数组去重,是因为在一次面试中(这家公司做的产品是协同开发级别的软件),让我对数组去重有了更进一步的了解。感兴趣的朋友们可以接着往下看。
数组去重
何为数组去重?给你一串数组,数组里面包含重复的数字和非数字,对数组去重,将重复的元素去掉,得到一串数据都是唯一的数组。数组形式如下所示。
const arr = [
1,
2,
2,
"abc",
"abc",
true,
true,
false,
false,
undefined,
undefined,
NaN,
NaN
];
数组去重还是挺重要的,最直接的作用就是可以使数据结构更清晰。当我们在处理数据的时候,有时候就会对数据进行去重处理,接下来我们就来实现数组去重的方法。
方法实现
关于数组去重实现的方法有很多,这里我们将介绍三种方法。
Set方法
先来说一种最简单直接的API
方式,代码如下所示。
const result = Array.from(new Set(arr));
console.log(result);
// [ 1, 2, 'abc', true, false, undefined, NaN ]
Set
中的元素都是不重复的,Set
对象仅能存储不同的值,因此达到去重的效果。
forEach()结合includes()
forEach
方法用来遍历数组,includes
方法用来检测数组是否有某个值。实现代码如下。
function removeNumber(arr) {
const newarr = [];
arr.forEach((element) => {
if (!newarr.includes(element)) {
newarr.push(element);
}
});
return newarr;
}
我当时面试的时候跟面试官说的就是这种方法,不过面试官接着问我这个方法的时间复杂度。我当时不假思索,认为是一层循环,直接说是O(n)
。面试官说我没有考虑includes
的时间复杂度,实际上在includes
里面还有一层循环,我确实是忽略了,所以这种方法的时间复杂度不是O(n)
。然后这时候我就想到了接下来的这种方法,也是面试官认可的方法。
利用对象的属性
利用对象的属性不能相同的特点进行去重,也是可以考虑的一种方法。代码如下所示。
function removeNumber1(arr) {
const newarr = [];
const obj = {};
arr.forEach((item) => {
if (!obj[item]) {
newarr.push(item);
obj[(item = true)];
}
});
return newarr;
}
这种方法如果单从时间复杂度上看,只有forEach
循环一遍,所以是O(n)
,达到了当时面试官想要的要求。不过我在此次面试之前觉得这种方法不好理解,并且这种方法有问题,所以我并没有练习这种方法,在面试的时候只会手写前一种方法,然后当时也只是说了利用对象属性不能相同来进行去重的思路,并没有成功手写出来。
最后经过这次面试,让我对这种方法有了深刻的印象,面试过后也对该方法进行了多次练习和理解。
总结
这就是我在其中一次面试中对数组去重的一次总结,也算是我对数组去重的巩固。我们总共介绍了三种方式,分别是Set
方法、forEach
()结合includes
()、利用对象的属性,这三种方法各有各的特点,都能达到去重的效果。
数组去重是面试中出现频率非常高的题目,也是在项目开发中经常能用到的方法,关于数组去重的方法不止这三种,还有更多方法,比如hasOwnProperty
去重、Map
数据结构去重(和Set
同理)等等,希望大伙可以多去看看,多去理解。
转载自:https://juejin.cn/post/7283060133646254116