数组去重一般在面试题出现的概率比较高,网上也有各种各样的解法,暂时总结七种比较好用的解法(后续会持续更新)
1. ES6 Set()
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Array.from()可以将各种值转为真正的数组,并且还提供map功能。
let arr = [3, 4, 3, '4', true,'a','a', true,false, false, undefined, undefined, null, null, NaN, NaN]
console.log(Array.from(new Set(arr))); //[3,4,'4',true,'a',false,undefined,null,NaN]
向 Set 加入值的时候,不会发生类型转换,所以4和"4"是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是向 Set 加入值时认为NaN等于自身,而精确相等运算符认为NaN不等于自身。
2. ES5 sort()
sort()先对其排序,后循环遍历比较相邻的值,
注意点:在判断相等时会隐式转换,所以导致4和'4'变成相同的值
let arr = [3, 4, 3, '4', true, 'a',true,false, false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
arr = arr.sort(); //1.先排序
let arr1 = [arr[0]];
for (let i = 1; i < arr.length; i++) {
if (arr[i] != arr[i - 1]) {
arr1.push(arr[i]);
}
}
return arr1;
}
console.log(arrNew(arr));[3,4,NaN,NaN,'a',false,null,true,undefined]
3.ES6 for...of +Obejct
for...of 语句创建一个循环来迭代可迭代的对象。遍历可迭代对象定义要迭代的数据。
同时利用对象的属性不会重复的特性
let arr = [3, 4, 3, '4', true, 'a', true,false,false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
let arr1 = [];
let obj = {};
for (let i of arr) {
if (!obj[i]) {
arr1.push(i);
obj[i] = 1;
}
}
return arr1;
}
console.log(arrNew(arr));[3,4,true,'a',false,undefined,null,NaN]
4.ES5 indexOf()
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。如果要检索的字符串值没有出现,则该方法返回 -1。
let arr = [3, 4, 3, '4', true, 'a', true,false,false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
let arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (arr1.indexOf(arr[i]) === -1) {
arr1.push(arr[i])
}
}
return arr1;
}
console.log(arrNew(arr));//[3,4,'4',true,'a',false,undefined,null,NaN,NaN]
5.ES5 splice()
双重 for 循环遍历数组,看两个值是否相等
splice会改变数组的长度,所以需要自减
let arr = [3, 4, 3, '4', true, 'a', true, false,false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length;j++) {
//在i的后一位
if (arr[i] == arr[j]) {
arr.splice(j, 1)
j--;
}
}
}
return arr;
};
console.log(arrNew(arr));//[3,4,true,'a',false,undefined,NaN,NaN];
6.ES6 for of + includes()
includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。
let arr = [3, 4, 3, '4', true, 'a', true,false, false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
let arr1 = [];
for (let i of arr) {
!arr1.includes(i) && arr1.push(i)
}
return arr1;
};
console.log(arrNew(arr));//[3,4,'4',true,'a',false,undefined,null,NaN]
7.ES6 Array filter()
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
filter() 不会对空数组进行检测,不会改变原始数组。
let arr = [3, 4, 3, '4', true, 'a', true, false,false, undefined, undefined, null, null, NaN, NaN]
function arrNew(arr) {
return arr.filter((item, index) => {
return arr.indexOf(item) === index
})
};
console.log(arrNew(arr)); //[3,4,'4',true,'a',false,undefined,null]