数组去重

今天总结一下数组去重的一些方法。记录一下。在真实的项目中碰到的数组去重,一般都是后台去处理,很少让前端处理这种问题。虽然日常项目用到的比较少,但我们还是需要了解一下,以防面试的时候可能回被问到。如果是被提问到,数组去重的方法有哪些?你能答出其中的几种?

一、利用 ES6 Set 去重

1
2
Array.from(new Set([1,2,3,3,4,4])) //[1,2,3,4]
[...new Set([1,2,3,3,4,4])] //[1,2,3,4]

set 是 ES6 新出来的一种一种定义不重复数组的数据类型
Array.from 是将类数组转化为数组
…是扩展运算符,将 set 里面的值转化为字符串

二、利用 for 嵌套 for,然后 splice 去重

1
2
3
4
5
6
7
8
9
10
11
12
13
function repeat(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
j--;
}
}
}
return arr;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。

三、利用 indexOf 去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function repeat(arr) {
if (!Array.isArray(arr)) {
return;
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i]);
}
}
return array;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

声明个空的结果数组,for 循环原数组,判断数组是否存在当前元素,如果有相同的值则跳过,不相同则 push 进数组。

四、利用 sort()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function repeat(arr) {
if (!Array.isArray(arr)) {
return;
}
arr = arr.sort();
var arrry = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
arrry.push(arr[i]);
}
}
return arrry;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

利用 sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对。

五、利用 includes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function repeat(arr) {
if (!Array.isArray(arr)) {
return;
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (!array.includes(arr[i])) {
array.push(arr[i]);
}
}
return array;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

六、利用 filter

1
2
3
4
5
6
7
function repeat(arr) {
return arr.filter(function (item, index, arr) {
return arr.indexOf(item, 0) === index;
});
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

七、利用递归去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function repeat(arr) {
var array = arr;
var len = array.length;
array.sort(function (a, b) {
return a - b;
});

function ditto(index) {
if (index >= 1) {
if (array[index] === array[index - 1]) {
array.splice(index, 1);
}
ditto(index - 1);
}
}
ditto(len - 1);
return array;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(repeat(arr)); //[1,2,3,4]

八、利用 js 的 prototype 属性给数组去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Array.prototype.distinct = 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;
}[(1, 2, 3, 3, 4, 4)].distinct(); //[1,2,3,4]

取新数组存值,循环两个数组值相比较

九、利用 Map 去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function arrays(arr) {
let map = new Map();
let array = new Array();
for (let i = 0; i < arr.length; i++) {
if (map.has(arr[i])) {
// 存在该key值
map.set(arr[i], true);
} else {
map.set(arr[i], false); // 不存在该key值
array.push(arr[i]);
}
}
return array;
}
var arr = [1, 2, 3, 3, 4, 4];
console.log(arrays(arr)); //[1,2,3,4]

我这边之前遇到了这样一个题目:用 js 实现随机选取 10-100 之间的 10 个数字,存入一个数组,去重后求和(保证这 10 个数字不能出现重复)要求:去重不能使用 Set,请完善下面的题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function sumOfRandomDistinctTenNumbers(){
//todo
}
我给出答案是
```js
function sumOfRandomDistinctTenNumbers(){
let arr = [];
let sum = 0;
for (let i = 0; i < 10; i++) {
arr[i] = parseInt(Math.random()*90 + 10);
}
arr = arr.filter((n) => {
sum += n;
return sum;
})
}

还有数组里面有多维,复杂类型的情况,直接上代码:

1
2
3
4
5
6
7
8
9
function unique(arr) {
let obj = {}
return arr.filter((item) => {
// key唯一
let newKey = item + JSON.stringify(item)
// 通过hasOwnProperty查找是否有自己的属性
return obj.hasOwnProperty(newKey) ? false : obj[newKey] = true
})
}