# 常见js去重

1.遍历数组法 它是最简单的数组去重方法(indexOf方法)

实现思路:新建一个数组,遍历去要重的数组,当值不在新数组的时候(indexOf为-1)就加入该新数组中;

function indexOfUniq(arr){
   var newarr = [];
   for(var i=0;i<arr.length;i++){
        if(newarr.indexOf(arr[i])==-1){
           newarr.push(arr[i])
        }
   }
   return newarr
}
1
2
3
4
5
6
7
8
9

2.数组下标判断法

调用indexOf方法,性能和方法1差不多

实现思路:如果当前数组的第 i 项在当前数组中第一次出现的位置不是 i,那么表示第 i 项是重复的,忽略掉。否则存入结果数组。

function indexOfUniq2(arr){
  var hash=[];
  for (var i = 0; i < arr.length; i++) {
     if(arr.indexOf(arr[i])==i){
      hash.push(arr[i]);
     }
  }
  return hash;
}
1
2
3
4
5
6
7
8
9

3.排序后相邻去除法 实现思路:给传入的数组排序,排序后相同的值会相邻,然后遍历排序后数组时,新数组只加入不与前一值重复的值。

function unique3(arr){
  arr.sort();
  var hash=[arr[0]];
  for (var i = 1; i < arr.length; i++) {
     if(arr[i]!=hash[hash.length-1]){
      hash.push(arr[i]);
     }
  }
  return hash;
}
1
2
3
4
5
6
7
8
9
10

4.优化遍历数组法(推荐)

实现思路:双层循环,外循环表示从0到arr.length,内循环表示从i+1到arr.length

将没重复的右边值放入新数组。(检测到有重复值时终止当前循环同时进入外层循环的下一轮判断)

function unique(quan_lst){    
    // d对象去重   
//去掉重复选取的数据
    for (var i = 0; i < quan_lst.length; i++) {
        for (var j =i+1; j <quan_lst.length; ) {
            if (quan_lst[i].photoid == quan_lst[j].photoid ) {//通过photoid属性进行匹配;
                quan_lst.splice(j, 1);//去除重复的对象;
            }else {
                j++;
            }
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

5.通过hash去重

function hashUniq(arr){
    var hashTable = arr.reduce((result,cur,index,arr)=>{
        result[cur] = true
        return result;
    },{})
    return Object.keys(hashTable).map(item => parseInt(item, 10));
}

笨方法:
function hashUniq1(arr){
   var obj = {},newarr = []
   for(var i = 0;i<arr.length;i++){
       obj[arr[i]] = arr[i]
   }
   var keys = Object.keys(obj);
   keys.map(ele=>{
       newarr.push(obj[ele])
   })
   return newarr
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

6.splice 去重(直接操作数组本身,带副作用)

function inPlaceUniq(arr) {
  let idx = 0;
  while (idx < arr.length) {
    let compare = idx + 1;
    while (compare < arr.length) {
      if (arr[idx] == arr[compare]) {
        arr.splice(compare, 1);
        continue;
      }
      ++compare
    }
    ++idx;
  }
  return arr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

7.ES6去重

function toSetUniq(arr) {
  return Array.from(new Set(arr));
}
function toSetUniq1(arr) {
  return Array.from(new Set(arr));
}
1
2
3
4
5
6

最后在nodejs下面简单跑个测试,看看哪个效率高~

let data = [];
for (var i = 0; i < 100000; i++) {
  data.push(Math.random())
}

// 实现一个性能测试的装饰器
function performanceTest(fn, descript) {
  var a = new Date().getTime();
  return function () {
    fn.apply(this, [].slice.call(arguments, 0));
    console.log(descript, new Date().getTime() - a)
  }
}

performanceTest(indexOfUniq, "indexOfUniq")(data)
performanceTest(indexOfUniq2, "indexOfUniq2")(data)
performanceTest(unique3, "unique3")(data)
performanceTest(unique, "unique")(data)
performanceTest(hashUniq, "hashUniq")(data)
performanceTest(hashUniq1, "hashUniq1")(data)
performanceTest(inPlaceUniq, "inPlaceUniq")(data)
performanceTest(toSetUniq, "toSetUniq")(data)
performanceTest(toSetUniq1, "toSetUniq1")(data)


indexOfUniq 3422ms
indexOfUniq2 3457ms
unique3 277ms
unique 4451ms
hashUniq 168ms
hashUniq1 200ms
inPlaceUniq 9977ms
toSetUniq 32ms
toSetUniq1 39ms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

事实证明当数据庞大的时候set去重为最优解 数据量小的时候hash去重比较适合

Last Updated: 4/15/2020, 5:02:25 PM