Artist Unknown

佚名艺术家


  • 首页
  • 归档
  • 关于 RITSU
  •   

© 2020 ritsu huang

Theme Typography by Makito

Proudly published with Hexo

关于数组去重的多种方法

发布于 2017-12-06

1.建立一个hash表 (适用于处理纯数字的数组,且此时速度最快)

思路: 利用对象的属性去重。遍历原数组的元素,然后在对象中访问这个属性,如果不存在,将该属性标记为true,并且push进新数组,如果存在就说明重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var arr = [1, 2, 2, 10, 3, 2, 3];

function uniqueHash(a) {
var hash = {},
len = a.length,
result = [];

for (var i = 0;i < len;i++){
if(!hash[a[i]]){
hash[a[i]] = true;
result.push(a[i]);
}
}

// console.log(hash[1] == hash['1'] ? 'yes' : 'no');

return result;
}

var arrNew = uniqueHash(arr);

console.log(arrNew);
// 输出:[ 1, 2, 10, 3 ]

注意:当不是纯数字数组时,数字1和字符串'1'会被视为是重复的元素而被去除。

1
2
3
4
5
var arr2 = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

var arrNew = uniqueHash(arr2);

// 输出:[ 1, 2, 10, 'a', 'b', '@' ]

2.基本法(借助新数组来判断重复)

思路: 定义一个新数组,并存放原数组的第一个元素,然后将原数组一一和新数组的元素对比,若不同则存放在新数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

function unique(arr) {
var result = [arr[0]];
for (var i = 1;i < arr.length;i++){
var repeat = false;
for(var j = 0;j < result.length;j++){
if(arr[i] === result[j]){
repeat = true;
break;
}
}
if(!repeat){
result.push(arr[i]);
}
}
return result;
}

var arrNew = unique(arr);

console.log(arrNew);

// 输出:[ 1, 2, 10, '1', '2', 'a', 'b', '@' ]

注意:这种方法最为通用,而且去重后的结果不会改变数组元素原本的顺序。

3.基本法二(在原数组内进行比较)

思路: 双层循环,外层循环元素,内层循环时比较值;如果有相同的值则跳过,不相同则push进新数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

Array.prototype.dedupe = function () {
var arr = this,
result = [],
i,
j,
len = arr.length;

for(i = 0;i < len;i++){
for(j = i + 1;j < len;j++){
if(arr[i] === arr[j]){
j = ++i;
}
}
result.push(arr[i]);
}
return result;
}

var arrNew = arr.dedupe();
console.log(arrNew);

// 输出:[ 1, 10, '1', '2', 'a', 'b', '@', 2 ]

注意:与上一方法类似的是也使用了双层for循环,但是没有借助新数组来比较,而是在原数组内比较。由于比较时遍历的顺序,对于重复的元素会取到排最后的一个元素,所以数组元素去重之后的顺序和之前的方法不太一样。

4.利用下标查询

思路: 利用数组的 indexOf 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

function uniqueIndex(arr) {
var result = [arr[0]];
for(var i = 0;i < arr.length;i++){
if(result.indexOf(arr[i]) === -1){
result.push(arr[i]);
}
}
return result;
}

var arrNew = uniqueIndex(arr);
console.log(arrNew);

// 输出:[ 1, 2, 10, '1', '2', 'a', 'b', '@' ]

思路2: 利用数组的 indexOf 以及 forEach 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];
Array.prototype.distinct = function () {
var arr = this,
result = [],
len = arr.length;

//这里利用map,filter方法也可以实现
arr.forEach(function (value,index,arr) {
var bool = arr.indexOf(value,index+1);
if(bool === -1){
result.push(value);
}
})
return result;
}

var arrNew = arr.distinct();
console.log(arrNew);

// 输出:[ 1, 10, '1', '2', 'a', 'b', '@', 2 ]

注意:这里面也是原数组内查找,而没有借用新数组,所以去重后数组元素的顺序不一样,同基本法二,对于重复的元素会取到排最后的一个元素。

5.利用ES6的set

思路: Set数据结构,类似于数组,其成员值都是唯一的;利用Array.from将Set结构转换成数组。

1
2
3
4
5
6
7
8
9
10
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

function dedupe(arr) {
return Array.from(new Set(arr));
}

var arrNew = dedupe(arr);
console.log(arrNew);

// 输出:[ 1, 2, 10, '1', '2', 'a', 'b', '@' ]

思路2: 使用扩展运算符(…)

1
2
3
4
5
6
7
"use strict"
var arr = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];

let result = [...new Set(arr)];
console.log(result);

// 输出:[ 1, 2, 10, '1', '2', 'a', 'b', '@' ]

6.利用Array.filter()方法

思路: 经赵老师指导,可用filter方法返回符合条件的新数组,在其回调函数内判断数组元素是否唯一。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var arrF = [1, 2, 2, 10, '1','2', 'a', 'a', 'b', '@', '@', 2];
var filtered = arrF.filter(function ( value , i ) {

return i === arrF.indexOf(value);

// 或者以下两种方式:
// return arrF.indexOf( value ,i + 1) === -1;
// return !arrF.includes(value ,i + 1);

});

console.log(filtered);

// 输出:[ 1, 2, 10, '1', '2', 'a', 'b', '@' ]

分享到 

 上一篇: 总结使用ESlint及其插件遇到的坑 下一篇: 数组乱序之洗牌算法 

© 2020 ritsu huang

Theme Typography by Makito

Proudly published with Hexo