数组去重是非常经典的面试题目。十次面试,能碰到十一次(这里带有夸张的成分)。这里之所以来讲一下数组去重,是因为在一次面试中(这家公司做的产品是协同开发级别的软件),让我对数组去重有了更进一步的了解。感兴趣的朋友们可以接着往下看。
const arr = [ 1, 2, 2, "abc", "abc", true, true, false, false, undefined, undefined, NaN, NaN ];
数组去重还是挺重要的,最直接的作用就是可以使数据结构更清晰。当我们在处理数据的时候,有时候就会对数据进行去重处理,接下来我们就来实现数组去重的方法。
const result = Array.from(new Set(arr)); console.log(result); // [ 1, 2, 'abc', true, false, undefined, NaN ]Set中的元素都是不重复的,Set对象仅能存储不同的值,因此达到去重的效果。
// 堆代码 duidaima.com 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()、利用对象的属性,这三种方法各有各的特点,都能达到去重的效果。