学习链接
数组去重
只考虑字符串和数字
Set
function unique(arr) {
return [...new Set(arr)];
}
filter + indexOf
function unique(arr) {
return arr.filter((item, index, arr) => {
return arr.indexOf(item) === index;
});
}
reduce + includes
function unique(arr) {
return arr.reduce((pre, cur) => {
if(!pre.includes(cur)) {
pre.push(cur);
}
return pre;
}, []);
}
测试
const arr = [123, "meili", "123", "mogu", 123];
console.log('unique(arr): ', unique(arr));
考虑对象
只考虑对象、不考虑属性顺序和NaN
function unique(arr) {
return [...new Set(arr.map(x => JSON.stringify(x)))].map(x => JSON.parse(x));
}
考虑对象属性顺序、NaN、Infinity
function unique(arr) {
const getArray = data => {
const str = Object.prototype.toString.call(data);
if(data
&& (str === '[object Object]' || str === '[object Array]')
) { // 非空对象/数组
const val = [];
Object.keys(data).sort().forEach(k => { // 排序处理对象名顺序的问题
val.push([k, getArray(data[k])]); // 递归处理值
});
return val;
} else { // 原始类型 | null
return data;
}
};
const getType = data => {
if(data === undefined
|| data === Infinity
|| data === -Infinity
|| Object.is(data, NaN)
) {
return data;
} else {
return JSON.stringify(getArray(data));
}
};
const arrStr = arr.map(item => ({
val: item,
type: getType(item)
}));
const map = new Map();
return arrStr
.filter(item => !map.has(item.type) && map.set(item.type, item.val))
.map(item => item.val);
}
const arr1 = [123, "meili", "123", "mogu", 123];
const arr2 = [123, [1, 2, 3], [1, "2", 3], [1, 2, 3], "meili"];
const arr3 = [123, {a: 1}, {a: {b: 1}}, {a: "1"}, {a: {b: 1}}, "meili"];
const arr4 = [{b: 1, c: 2}, {c: 2, b: 1}];
const arr5 = [undefined, null, undefined, null];
const arr6 = [NaN, Infinity, -Infinity, NaN, Infinity, -Infinity];
const arr7 = [NaN, null];
console.log('unique(arr1): ', unique(arr1));
console.log('unique(arr2): ', unique(arr2));
console.log('unique(arr3): ', unique(arr3));
console.log('unique(arr4): ', unique(arr4));
console.log('unique(arr5): ', unique(arr5));
console.log('unique(arr6): ', unique(arr6));
console.log('unique(arr7): ', unique(arr7));
// 函数、日期对象、正则表达式无法正确去重
function fun1(){let x = 5}
function funny(){let z = 5}
const date1 = new Date(1,1)
const date2 = new Date(1,2)
const arr8 = [fun1, funny];
const arr9 = [/a/, /abc/];
const arr10 = [date1, date2];
console.log('unique(arr8): ', unique(arr8));
console.log('unique(arr9): ', unique(arr9));
console.log('unique(arr10): ', unique(arr10));
JSON也无法处理循环对象结构