1. 双重循环去重
function unique(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {//第一个等同于第二个,splice方法删除第二个
arr.splice(j, 1);
j--;
}
}
}
return arr;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
2. indexOf includes findIndex find some filter 减少内层循环去重
indexOf
function unique(arr) {
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array.indexOf(arr[i]) === -1) {
array.push(arr[i])
}
}
return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
indexOf 接收元素,返回符合条件的第一个index,不存在时返回-1
includes 接收元素,返回boolean,不存在时返回false
findIndex 接收函数,返回符合条件的第一个index,不存在时返回-1
find 接收函数,返回符合条件的第一个元素,不存在时返回undefined
some 接收函数,匹配符合条件的第一个元素 返回boolean,不存在时返回false
filter 接收函数,匹配所有符合条件的元素,返回数组,不存在时返回空数组
includes
function unique(arr) {
var array = [];
for (var i = 0; i < arr.length; i++) {
if (!array.includes(arr[i])) {
array.push(arr[i])
}
}
return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
find
function unique(arr) {
var array = [];
for (var i = 0; i < arr.length; i++) {
if (!array.find((item) => item === arr[i])) {
array.push(arr[i])
}
}
return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
some
function unique(arr) {
var array = [];
for (var i = 0; i < arr.length; i++) {
if (!array.some((item) => item === arr[i])) {
array.push(arr[i])
}
}
return array;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
3. filter代替外层循环 indexof代替内层循环
function unique(arr) {
return arr.filter((item, index)=> {
// filter循环到的初次见面的元素会被return,第二个同种元素的indexOf会返回第一个同种元素的index而未通过校验,不return
return arr.indexOf(item) === index
})
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
4. sort排序 再遍历 相邻节点比较
function unique(array) {
var res = [];
var sortedArray = array.concat().sort();
var last;
for (var i = 0, len = sortedArray.length; i < len; i++) {
// 如果是第一个元素或者相邻的元素不相同
if (!i || last !== sortedArray[i]) {
res.push(sortedArray[i])
}
last = sortedArray[i];
}
return res;
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
Set
function unique(array) {
return Array.from(new Set(array));
}
function unique2(array) {
return [...new Set(array)];
}
let arr = [1, 1, 'true', 'true', true, true, 15, 15];
console.log(unique(arr))// [ 1, 'true', true, 15 ]
5. Object 键值对
function distinct(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
JS 数组去重怎么实现。(回答 Set)如果要对对象去重怎么做。
6. 额外的知识 几个类型的相等问题 以及无法去重的情况
let str1 = '123';
let str2 = new String('123');
console.log(str1 == str2); // true
console.log(str1 === str2); // false
console.log(null == null); // true
console.log(null === null); // true
console.log(undefined == undefined); // true
console.log(undefined === undefined); // true
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(/a/ == /a/); // false
console.log(/a/ === /a/); // false
console.log({} == {}); // false
console.log({} === {}); // false
indexOf 底层使用的是 === 进行判断,所以使用 indexOf 查找不到 NaN 元素
Set可以去重NaN类型, Set内部认为尽管 NaN === NaN 为 false,但是这两个元素是重复的
// 比较
var array = [1, 1, '1', '1', null, null, undefined, undefined, new String('1'), new String('1'), /a/, /a/, NaN, NaN];
Array.sort()加一行遍历冒泡 无法去重 对象 和 NaN 和 数字1
双重For循环 无法去重 对象 和 NaN
filter+indexOf 无法去重 对象 和 NaN消失
Set去重 无法去重 对象
Object 键值对去重 全部去重
大佬的测试结果
双重 for 循环 > Array.filter()加 indexOf > Array.sort() 加一行遍历冒泡 > Object 键值对去重复 > ES6中的Set去重