javascript-数组去重

1. 双层for循环法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var unique = function (arr) {
var res = [];
for (var i = 0, arrLen = arr.length; i < arrLen; i++) {
for (var j = 0, resLen = res.length; j < resLen; j++) {
if (arr[i] === res[j]) {
break;
}
}
// j === resLen 表明遍历整个 res 数组结束后仍没找到和 arr[i] 相等的值,故插入 res 数组
if (j === resLen) {
res.push(arr[i]);
}
}
return res;
}

// 测试
var testArray = [1, 2, 1, 3, '1'];
console.log(unique(testArray)); // [1, 2, 3, '1']

2. indexOf 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var unique = function (arr) {
var res = [];
for (var i = 0, len = arr.length; i < len; i++) {
var current = arr[i];
if (res.indexOf(current) === -1) {
res.push(current);
}
}
return res;
}

// 测试
var testArray = [1, 2, 1, 3, '1'];
console.log(unique(testArray)); // [1, 2, 3, '1']

3. 具有简单定制功能的去重函数

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
// arr 传入的需去重的数组
// isSorted 是否经过排序,如果经过排序可使用一种更高效的方法,传入值为true或false
// func 可以对去重数组进行操作,需带有返回值,如将字母都转换成小写
var unique = function (arr, isSorted, func) {
var res = [];
var pre = null;
for (var i = 0, len = arr.length; i < len; i++) {
var value = arr[i];
var computed = func ? func(value, i, arr) : value;
if (isSorted) {
if (!i || pre !== computed) {
res.push(computed);
}
pre = computed;
} else {
if (res.indexOf(computed) === -1) {
res.push(computed);
}
}
}
return res;
}
// 测试
var testArray = [1, 1, 'a', 'A', 2, '2'];
console.log(unique(testArray, false, function(item){
return typeof item == 'string' ? item.toLowerCase() : item
})); // [1, 'a', 2, '2']

4. Object 键值对方法

1
2
3
4
5
6
7
8
9
let unique = function (arr) {
var obj = {};
return arr.filter(function (item) {
return obj.hasOwnProperty(typeof item + JSON.stringify(item)) ? false : (obj[typeof item + JSON.stringify(item)] = true);
});
}
// 测试
let testArray = [{value: 1}, {value: 1}, {value: 2}];
console.log(unique(testArray));

5. filter

1
2
3
4
5
6
7
8
9
10
11
// 原数组未排序
const unique = arr => arr.filter((item, index, arr) => arr.indexOf(item) === index);
// 测试
let testArray = [1, 1, 1, 'a', 'a'];
console.log(unique(testArray)); // [1, 'a']

// 原数组已排序
const unique = arr => arr.filter((item, index, arr) => (!index || item !== arr[index - 1]));
// 测试
let testArray = [1, 1, 1, 'a', 'a'];
console.log(unique(testArray)); // [1, 'a']

6. ES6 中的两个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// set
const unique = a => [...new Set(a)];
// 测试
let testArray = [1, 1, 2, '1'];
console.log(unique(testArray)); // [1, 2, '1']

// map
const unique = function (arr) {
let temp = new Map();
return arr.filter(a => !temp.has(a) && temp.set(a, 0));
};
// 测试
let testArray = [1, 1, 2, '1'];
console.log(unique(testArray)); // [1, 2, '1']

7. 注意事项

以上所述的去重方法中,其中只有“Object 键值对方法”实现了对于数组成员是对象或 NaN 的去重,Set 方法实现了对 NaN 的去重。

要结合自己的使用场景选择合适的去重方法。

8. Referrence

JavaScript专题之数组去重