1、indexOf
function uniqueIndexOf(arr){
var result = [];
for (let i = 0, len = arr.length; i < len; i++) {
if (result.indexOf(arr[i]) === -1) {
result.push(arr[i]);
}
}
return result;
}
2、fiter+indexOf
function uniqueFilterIndexOf(arr) {
return arr.filter(function(item, index, array){
return array.indexOf(item) === index;
});
}
3、includes
function uniqueIncludes(arr) {
var result = [];
for (let i = 0, len = arr.length; i < len; i++) {
if (!result.includes(arr[i])) {
result.push(arr[i]);
}
}
return result;
}
4、sort
function uniqueSort(arr) {
var result = [];
var prevItem = arr[0];
var newArr = arr.concat().sort();
for (let i = 0, len = newArr.length; i < len; i++) {
if (!i || prevItem !== newArr[i]) {
result.push(newArr[i]);
}
prevItem = newArr[i];
}
return result;
}
5、filter+sort
function uniqueFilterSort(arr) {
return arr.concat().sort().filter(function(item, index, array){
return !index || item !== array[index - 1];
});
}
6、object键值
function uniqueObject(arr) {
var obj = {};
return arr.filter(function (item, index, array) {
let key = typeof item + JSON.stringify(item);
return obj.hasOwnProperty(key) ? false : (obj[key] = true);
});
}
对象类型obj[1]与obj['1']是一致的,因为对象的键值只能是字符串, 还有如下结果
JSON.stringify(NaN); // 'null'
JSON.stringify(null); // 'null'
JSON.stringify(NaN) === JSON.stringify(null) // true
所以使用typeof item + JSON.stringify(item) 作为唯一key
7、set
function uniqueSet(arr) {
return [...new Set(arr)];
}
8、set + from
function uniqueSetFrom(arr) {
return Array.from(new Set(arr));
}
9、改进
如果数组中要求不区分大小写,如
var arr = [1, 'a', 'A', 2];
function uniqueIncludesIteratee(arr, iteratee) {
var result = [];
var seen = [];
for (let i = 0, len = arr.length; i < len; i++) {
let item = arr[i];
let computed = iteratee ? iteratee(item, i, arr) : item;
if (seen.indexOf(computed) === -1) {
seen.push(computed);
result.push(item);//注意此句是item,而不是computed
}
}
return result;
}
uniqueIncludesIteratee(arr, function(item, index, array){
return typeof item == 'string' ? item.toLowerCase() : item;
});
//[1, 'a', 2]
结论
var str1 = new String('1');
var str2 = '1';
1 == 1 //true
1 === 1 //true
'1' == '1' //true
'1' === '1' //true
null == null //true
null === null //true
undefined == undefined //true
undefined === undefined //true
str1 == str2 //true
str1 === str2 //false
/a/ == /a/ //false
/a/ === /a/ //false
NaN == NaN //false
NaN === NaN //false
var arr = [
1, 1,
'1', '1',
null, null,
undefined, undefined,
new String('1'), new String('1'),
/a/, /a/,
NaN, NaN
];
uniqueIndexOf(arr);
| 方法名称 | 结果 | 说明 |
|---|---|---|
| indexOf | [1, "1", null, undefined, String, String, /a/, /a/, NaN, NaN] | NaN和对象都不去重 |
| filter + indexOf | [1, "1", null, undefined, String, String, /a/, /a/] | NaN被忽略,对象不去重 |
| includes | [1, "1", null, undefined, String, String, /a/, /a/, NaN] | NaN去重,对象不去重 |
| sort | [/a/, /a/, 1, "1", String, String, NaN, NaN, null, undefined] | NaN和对象都不去重 |
| filter + sort | [/a/, /a/, 1, "1", String, String, NaN, NaN, null, undefined] | NaN和对象都不去重 |
| object | [1, "1", null, undefined, String, /a/, NaN] | 都去重(对于顺序不同的对象数据还是有问题) |
| set | [1, "1", null, undefined, String, String, /a/, /a/, NaN] | NaN去重,对象不去重 |
| set + from | [1, "1", null, undefined, String, String, /a/, /a/, NaN] | NaN去重,对象不去重 |
[NaN].indexOf(NaN) //-1
[NaN].includes(NaN) //true
主要对于NaN和对象类型数据的判断,存在不同