关于数组去重的总结

关于JS数组去重的方法总结

方法一:

  • 双层循环,外层循环元素,内层循环时比较值。如果有相同的值则跳过,不相同则push进数组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //常规方法
    function unique(arr){
    var res = [];
    for (var i = 0; i < arr.length; i++) {
    for (var j = i+1; j < arr.length; j++) {
    if (arr[i] === arr[j]) {
    j = ++i;
    }
    }
    res.push(arr[i]);
    }
    return res;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 类似写法,主要思路和判断方法是一样的,只是细节有点小改动
function unique(arr){
var res = [arr[0]];
for (var i = 1; i < arr.length; i++) {
var repeat = false;
for (var j = 0; j < res.length; j++) {
if (arr[i] === res[j]) {
repeat = true;
break;
}
}
if (!repeat) {
res.push(arr[i]);
}
}
return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//类似思路:主要都是通过双重循环遍历,利用splice直接在原数组进行操作
//双层循环,外层循环元素,内层循环时比较值
//值相同时,则删去这个值
//注意点:删除元素之后,需要将数组的长度也减1.
Array.prototype.unique = function (){
var arr = this,
i,
j,
len = arr.length;
for(i = 0; i < len; i++){
for(j = i + 1; j < len; j++){
if(arr[i] == arr[j]){
arr.splice(j,1);
len--;
j--;
}
}
}
return arr;
};
var a = [1,2,3,4,5,6,5,3,2,4,56,4,1,2,1,1,1,1,1,1,];
var b = a.unique();
console.log(b.toString()); //1,2,3,4,5,6,56

方法二

  • 利用indexOf()方法,下标索引查询,需要考虑indexOf该方法的兼容性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var indexOf = [].indexOf
    ?
    function indexOf(arr,item){
    return arr.indexOf(item);
    }
    :
    function indexOf(arr,item){
    for (var i = 0; i < arr.length; i++) {//这里遍历方法可以选择forEach,map,filter方法也可以实现,看你喜欢.
    if (arr[i] === item) {
    return i;
    }
    }
    return -1;
    }
    function unique(arr){
    var res = [];
    for (var i = 0; i < arr.length; i++) {
    if (res.indexOf(arr[i]) === -1) {
    res.push(arr[i]);
    }
    }
    return res;
    }

方法三(推荐)

  • 利用对象的属性不能相同的特点进行去重,考虑性能和优化
  • 创建一个新的数组存放结果
  • 创建一个空对象
  • for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
    说明:每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function unique(arr){
    var res = [],
    hashObj = {};
    for (var i = 0; i < arr.length; i++) {
    //注意:在 JavaScript 里,对象的键值只能是字符串,因此需要 var key = typeof(item) + item 来区分数值 1 和字符串 '1' 等情况
    var item = arr[i],
    key = typeof(item) + item;
    if (!hashObj[key]) {
    res.push(item);
    hashObj[key] = 1;
    }
    }
    return res;
    }

方法四

  • 先排序再去重,先将原数组排序,与相邻的进行比较,如果不同则存入新数组
    1.先将原数组进行排序
    2.检查原数组中的第i个元素与结果数组中的最后一个元素是否相同,因为已经排序,所以重复元素会在相邻位置
    3.如果不相同,则将该元素存入结果数组中
1
2
3
4
5
6
7
8
9
10
11
12
function unique(arr){
var sortArr = arr.sort(function(value1,value2){
return value1 - value2;
});
var res = [sortArr[0]];
for (var i = 1; i < sortArr.length; i++) {
if (sortArr[i] !== res[res.length - 1]) {
res.push(sortArr[i]);
}
}
return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//写法二
Array.prototype.unique2 = function(){
this.sort(); //先排序
var res = [this[0]];
for(var i = 1; i < this.length; i++){
if(this[i] !== res[res.length - 1]){
res.push(this[i]);
}
}
return res;
}
var arr = [1, 'a', 'a', 'b', 'd', 'e', 'e', 1, 0]
alert(arr.unique2());

注意:
1.原数组的数据类型需要考虑
2.该方法存在一定的局限性,因为在去重前进行了排序,所以最后返回的去重结果也是排序后的。如果要求不改变数组的顺序去重,那这种方法便不可取了。

方法五

  • 数组递归去重 + splice方法
  • 运用递归的思想,先排序,然后从最后开始比较,遇到相同,则删除
    注意:
  • 同样的,这种方法和上面“排序去重”都存在相同缺陷
    1.原数组的数据类型需要考虑
    2.该方法存在一定的局限性,因为在去重前进行了排序,所以最后返回的去重结果也是排序后的。如果要求不改变数组的顺序去重,那这种方法便不可取了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    function unique(arr){
    //对数组进行排序才能方便比较
    var sortArr = arr.sort(function(value1,value2){
    return value1 - value2;
    });
    function loop(index){
    if (index >= 1) {
    if (sortArr[index] === sortArr[index - 1]) {
    sortArr.splice(index,1);
    }
    loop(index - 1);//递归loop函数进行去重
    }
    }
    loop(sortArr.length - 1);
    return sortArr;
    }

方法六

  • 利用ES6的set
  • Set数据结构,它类似于数组,其成员的值都是唯一的。

1.利用Array.from将Set结构转换为数组

1
2
3
4
function unique(arr){
return Array.from(new Set(arr));
}
console.log(unique(arr1));

2.使用拓展运算符(…),内部使用for…of循环

1
2
3
4
let uniqueArr = [...new Set(arr)];
// 或者
var arr2 = [1,2,3,2,1,'1','2','a','b','aa','b','c'];
console.log([...new Set(arr2)]);

总结:上述关于数组去重的方法各都存在优缺点,对于性能也有所不同,细节之处需要慢慢去体会。文章仅作为博主学习总结使用,如发现有任何侵权行为,请立马联系我。

参考:
数组去重的四种方法
再见,重复的你(数组去重)
玉伯:从js数组去重谈性能优化


博主前端小白,才疏学浅,若发现文章有任何不妥的地方,可直接E-mail!

“An essential part of creativity is not being afraid to fail.”

-------------我是有底线的-------------
谢谢您给我的卡布奇诺(*^_^*)