数组去重的几种方法和性能

数组去重应该是面试必答题了吧,那么数组去重有哪些方法呢?哪种方法的性能比较高呢?

我写了一个测试模板来验证,分别创建了两个长度为 10W 和 5W 的数组,然后通过 distinct() 方法合并两个数组,并去掉其中的重复项

方法一:Array.filter() + indexOf

使用 ES6 的Array.filter() 遍历数组,并结合 indexOf 来排除重复项

 1 mounted() {
 2     this.distinct_test('方法一:Array.filter() + indexOf');
 3   },
 4   methods:{
 5     distinct_test(desc){
 6       let arr1 = Array.from(new Array(100000), (x, index)=>{
 7       return index
 8     })
 9     let arr2 = Array.from(new Array(50000), (x, index)=>{
10       return index+index
11     })
12     console.log(desc)
13     let start = new Date().getTime()
14     console.log('开始数组去重')
15     function distinct(a, b) {
16      // 数组去重
17       let arr = a.concat(b);
18       return arr.filter((item, index)=> { return arr.indexOf(item) === index })
19     }
20     console.log('去重后的长度', distinct(arr1, arr2).length)
21     let end = new Date().getTime()
22     console.log('耗时', end - start)
23     }
24   },

 

 

 

 

 

方法二:双层for循环

最容易理解的方法,外层循环遍历元素,内层循环检查是否重复

当有重复值的时候,可以使用 push(),也可以使用 splice()

 1 function distinct(a, b) {
 2      // 数组去重
 3      let arr = a.concat(b);
 4      for (let i=0, len=arr.length; i<len; i++) {
 5       for (let j=i+1; j<len; j++) {
 6       if (arr[i] == arr[j]) {
 7         arr.splice(j, 1);
 8         // splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
 9         len--;
10         j--;
11       }
12       }
13       }
14         return arr
15     }

非常久!我一度怀疑程序出了问题...

 

方法三:for...of + includes()

双重for循环的升级版,外层用 for...of 语句替换 for 循环,把内层循环改为 includes()

1 function distinct(a, b) {
2      // 数组去重
3      let arr = a.concat(b);
4      let result = []
5      for (let i of arr) {
6      !result.includes(i) && result.push(i)
7       }
8       return result
9     }

 

方法四:Array.sort() 

首先使用 sort() 将数组进行排序

然后比较相邻元素是否相等,从而排除重复项

 1 function distinct(a, b) {
 2      // 数组去重
 3      let arr = a.concat(b);
 4      arr = arr.sort()
 5      let result = [arr[0]]
 6      for (let i=1, len=arr.length; i<len; i++) {
 7      arr[i] !== arr[i-1] && result.push(arr[i])
 8      }
 9       return result
10     }

 

方法五:for...of + Object

利用对象的属性不会重复这一特性,校验数组元素是否重复

 1 function distinct(a, b) {
 2      // 数组去重
 3      let arr = a.concat(b);
 4      let result = []
 5      let obj = {}
 6      for (let i of arr) {
 7       if (!obj[i]) {
 8        result.push(i)
 9         obj[i] = 1
10       }
11       }
12       return result
13     }

哟呵!超快der~  

 

方法六:new set()

ES6 新增了 Set 这一数据结构,类似于数组,但 Set 的成员具有唯一性

基于这一特性,就非常适合用来做数组去重了

1 function distinct(a, b) {
2      // 数组去重
3      return Array.from(new Set([...a, ...b]))
4     }

代码简洁,速度也挺快

 

方法七:利用Map数据结构去重

 1 function distinct(a, b) {
 2      // 数组去重
 3       let arr = a.concat(b);
 4       let map = new Map();
 5       let array = new Array(); // 数组用于返回结果
 6       for (let i = 0; i < arr.length; i++) {
 7          if(map .has(arr[i])) { // 如果有该key值
 8           map .set(arr[i], true); } 
 9           else { 
10           map .set(arr[i], false); // 如果没有该key值
11           array .push(arr[i]);
12          }
13       } 
14       return array ;
15     }

 

方法八:reduce+includes

1 function distinct(a, b) {
2      // 数组去重
3       let arr = a.concat(b);
4       return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
5     }

 

这么一比较,结果应该很明显了吧

 

posted @ 2022-09-23 10:40  laya1211  阅读(147)  评论(0)    收藏  举报