数组去重是日常工作经常出现的场景,解决办法有多种,简洁的、详细的等等,举例我用到过的方法
利用数组对象的唯一性
object.hasOwnProperty(prop),返回一个布尔值,对象自身中是否有该属性,忽略从原型链上继承的属性,兼容性强
// 数组去重
const array = [{ value: 1 }, { value: '1' }, { value: 2 }, '1', 1, 1]
const notReapeatedArray = []
let notReapeatedObj = {}
for (let index = 0; index < array.length; index++) {
const prop = array[index];
// 去除JS强制类型转换的干扰,比如1、"1"是不相等的
const rely = prop + JSON.stringify(prop)
// hasOwnProperty不会遍历原型链上的属性
if (!notReapeatedObj.hasOwnProperty(rely)) {
notReapeatedObj[rely] = true
notReapeatedArray.push(prop)
}
}
// [ { value: 1 }, { value: '1' }, { value: 2 }, '1', 1 ]
console.log(notReapeatedArray);
两次for循环
// 数组去重
const array = ['1', 1, '1', ['15'], 15]
// 没有重复项的数组,待push
const notReapeatedArray = []
for (i = 0; i < array.length; i++) {
// 遍历数组的每一项,是否在notReapeatedArray中出现过,若是,跳出循环,否则放到notReapeatedArray里
for (j = 0; j < notReapeatedArray.length; j++) {
if (array[i] === notReapeatedArray[j]) {
// 有相同项出现了,直接跳出循环,说明array[i]已经存在了
break
}
}
// array[i] 在数组notReapeatedArray中循环后未出现过,j肯定是notReapeatedArray的长度,因为每一项都被循环了
if (j == notReapeatedArray.length) {
notReapeatedArray.push(array[i])
}
}
console.log(notReapeatedArray);//[ '1', 1, [ '15' ], 15 ]
filter遍历,结合indexOf,兼容ie9及以上
filter返回一个新数组,其中包含所有符合过滤规则的元素,兼容ie9及以上,兼容旧环境,polyfill,点我
indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1,兼容ie9及以上;兼容旧环境,polyfill,点我
把polyfill加到代码中即可
// 使用filter方便判断当前项是否和上一项相同
const array = ['1', 1, '1', ['15'], 15]
const notReapeatedArray = array.filter((item, index) => {
return array.indexOf(item) === index
})
console.log(notReapeatedArray);//[ '1', 1, [ '15' ], 15 ]
ES6 Set对象
Set中的元素只会出现一次,即Set中的元素是唯一的
ES6的兼容性经过babel处理就行啦
const array = ['1', 1, '1', ['15'], 15]
const notReapeatedArray = new Set(array)
//返回一个Set对象,Set { '1', 1, [ '15' ], 15 }
console.log(notReapeatedArray);
//用Array.from 转成Array
Array.from(notReapeatedArray)//[ '1', 1, [ '15' ], 15 ]
// 用...操作符把Set转换成Array
console.log([...notReapeatedArray]);//[ '1', 1, [ '15' ], 15 ]