1、reduce + indexOf || reduce + includes
const arrnodouble = (arr) => {
let res = arr.reduce((prearr, curval) => {
if (prearr.indexOf(curval) == -1) { // if (!prearr.includes(curval)) {
prearr.push(curval)
}
return prearr
}, [])
return res
}
console.log(arrnodouble([1, 1, 3, 5, 2, 3, 5, 1, 2, 5]));
tips:reduce()方法返回的是数组中每个元素执行完reducer函数的值,这里返回的相当于是返回执行完reduce函数的prearr的结果,prearr是一个数组,所以最后返回的是一个去重的数组。
初始值为啥为[],因为第一次执行回调函数时,不存在”上一次的计算结果“,如果需要回调函数从索引为0开始执行,就需要传递初始值。否则,则从第二个元素开始执行。
若是还不能理解,则看mdnArray.prototype.reduce() - JavaScript | MDN
2、indexOf || includes
const arrnodouble = (arr) => {
let res = []
for (let i = 0; i < arr.length; i++) {
// indeOf不能将NaN和{}去重
// [1, 'true', true, 15, false, undefined, null, NaN, NaN, 'NaN', 0, 'a', {…}, {…}]
// if (res.indexOf(arr[i]) == -1) {// if (!res.includes(arr[i])) {
// res.push(arr[i])
// }
// includes不能将{}去重
// [1, 'true', true, 15, false, undefined, null, NaN, 'NaN', 0, 'a', {…}, {…}]
if (!res.includes(arr[i])) {
res.push(arr[i])
}
}
return res
}
console.log(arrnodouble([1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}]));
3、splice
const arrnodouble = (arr) => {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1)
}
}
}
return arr
}
console.log(arrnodouble([1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}]));
不能去重NaN和{}
4、sort
const arrnodouble = (arr) => {
arr = arr.sort((a, b) => a - b)
let res = [arr[0]]
for (let i = 1; i < arr.length; i++) {
if (arr[i] !== arr[i - 1]) {
res.push(arr[i])
}
}
return res
}
console.log(2, arrnodouble([1, 1, 'true', 'true', true, true, 15, 15, false, false, undefined, undefined, null, null, NaN, NaN, 'NaN', 0, 0, 'a', 'a', {}, {}]));
不能去重NaN和{}
5、filter
const arrnodouble = (arr) => {
let res = arr.filter((item, index) => {
return arr.indexOf(item, 0) == index
})
return res
}
直接去掉了NaN,不能去重{}
6、set(没有人会拒绝一行代码吧)
const arrnodouble = (arr) => {
return [...new Set(arr)]
}
7、对象的属性不能相同
const arrnodouble = (arr) => {
let obj = {}
let res = []
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
res.push(arr[i])
obj[arr[i]] = 1
}
}
return res
}
去重了NaN和{},但是两个true都去掉了
8、hasOwnProperty() + filter
const arrnodouble = (arr) => {
let obj = {}
let res = arr.filter(item => {
if (obj.hasOwnProperty(typeof item + item)) {
return false
} else {
obj[typeof item + item] = true
return true
}
})
return res
}
借用另外一个博主的话:
这里的typeof item + item
可以输出"item数据类型 + item值"
的字符串结果,然后通过hasOwnPrototype()
来判断obj
内是否有这个数据类型的数据(hasOwnPrototype()不会攀升原型链),如果有那么就直接返回false,根据filter()
的用法,这个数据就会被过滤掉。
如果这个obj
内没有这个类型的数据,那么就会通过obj[数据类型]
的方式将这个类型存入obj中,并且设定值为true,同时这个数据根据filter()
的用法,会保留。
总结就是:无非是两种方法:两层循环 || 语法自身键不可重复性。方法还有很多,这几种比较常见。