目录
方法七、利用 filter() + indexOf() 去重
方法九、 利用 reduce() + includes() 去重
数组去重是我们经常会遇到的题目,我总结了9种方法来实现这个功能,一起来看看吧!
注:在下面的示例中,我采用的数据非常特殊,出现了很多数据类型,如: {} 、 NaN、true 等。在实际应用场景中,不会有那么多特殊的数据,一般是正常的数据。这里只是为了突出它们的区别。
方法一、最常使用,也最容易想到的思路( ES5 ):
使用for循环,双层遍历,当内层循环的值等于外层循环的值,则将内层循环的值,使用 splice() 删除
/*
方法一:最常使用,也最容易想到的思路:
使用for循环,双层遍历,
当内层循环的值等于外层循环的值,则将内层循环的值,使用splice删除
*/
function unique1(arr){
for(let i=0;i<arr.length;i++){
for(let j=i+1;j<arr.length;j++){
// 如果二者相同,则进行删除
if(arr[i] === arr[j]){
// 删除下标为j的这个元素
arr.splice(j,1)
// splice方法会改变元素组的大小,所以每删除一个元素,这里要j--
j--
}
}
}
return arr
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log(unique1(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是15,其中,重复的 {} 、NaN 并没有被删除。原因是 {} 不等于 {} ,NaN 不等于 NaN
上述代码的简化版本:只要 var newArr = [...new Set(arr)] 这一行足够,但是重复的 {} 、NaN 并没有被删除。
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
var newArr = [...new Set(arr)]
console.log(newArr)
方法二、ES6 Set() 去重( ES6 中最常用)
使用 Set() 将 arr 去重后,再转换为数组
/*
方法二:ES6的Set去重
使用Set将arr去重后,再转换为数组
*/
function unique2(arr){
return Array.from(new Set(arr))
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique2(arr))
打印结果如下:可以看出,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 没有被去除
方法三、使用 indexOf 去重
indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置,如果没有找到匹配的字符串则返回 -1。注意: indexOf() 方法,在判断是否匹配时,区分大小写。
可以利用 indexOf 来实现去重
/*
方法三:indexOf() 方法返回某个指定的字符串值在字符串中首次出现的位置
*/
function unique3(arr){
// 新建一个空数组,存放去重之后的数组元素
var array = []
for(var i=0;i<arr.length;i++){
// 如果新数组array中,没有旧数组arr的下标为i对应的元素,则添加到新数组中
// 注意要使用全等符号
if(array.indexOf(arr[i]) === -1){
array.push(arr[i])
}
}
return array
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique3(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是15,其中,重复的 {}、NaN 并没有被删除。
方法四、使用 sort() 排序去重
/*
方法四:使用sort()排序,比较前后相邻元素是否相同
*/
function unique4(arr){
arr.sort()
// 排序之后,第一个元素要么是唯一的,要么是和后面的元素重复
// 把旧数组的第一个元素之间添加到新数组array中
var array = [arr[0]]
for(var i=1;i<arr.length;i++){
if(arr[i] !== arr[i-1]){
array.push(arr[i])
}
}
return array
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log(arr.sort())
console.log("原数组的长度是:",arr.length)
console.log(unique4(arr))
注意:在排序的时候,布尔值 true 是无法判断该放在哪个后面的,所以后面去重时,由于排序导致的问题,重复的 “true” 没有被完全去除。此外,重复的 {} 和 NaN 也没有被去除。
方法五、使用 includes() 去重
includes() 方法用于判断字符串是否包含指定的子字符串。如果找到匹配的字符串则返回 true ,否则返回 false 。注意: includes() 方法区分大小写。
/*
方法五:使用includes
*/
function unique5(arr){
// 新建一个空数组,存放去重之后的数组元素
var array = []
for(var i=0;i<arr.length;i++){
//includes 判断数组是否有某个值
if(!array.includes(arr[i])){
array.push(arr[i])
}
}
return array
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique5(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。
方法六、利用 hasOwnProperty() 去重
hasOwnProperty() 方法用于检测一个对象是否含有特定的自身属性,返回一个布尔值。typeof item + item 是数组的元素 item 的类型与值拼接在一起,作为 obj 对象的属性,这个属性是唯一的,在遍历过程中,如果 obj 中有这个属性,则不会添加到 obj 对象上,达到去重的效果。
/*
方法六:利用hasOwnProperty
*/
function unique6(arr){
var obj = {}
return arr.filter(function(item,index,arr){
//typeof item + item是数组的元素item的类型与值拼接在一起,作为obj对象的属性,这个属性是唯一的
//如果obj中有这个属性,则不会添加到obj对象上,达到去重的效果
return obj.hasOwnProperty(typeof item + item)?false:(obj[typeof item +item] = true)
})
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique6(arr))
打印结果如下:可以发现,所有的元素都去重了。
方法七、利用 filter() + indexOf() 去重
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测, filter() 不会改变原始数组。
/*
方法七:利用filter + indexOf
*/
function unique7(arr){
return arr.filter(function(item,index,arr){
// arr.indexOf(item,0)是元素item首次出现的位置,
// 如果与当前的索引值index相等,说明该元素item之前从未出现过
return arr.indexOf(item,0) === index
})
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique7(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是13,其中,重复的 {} 并没有被删除。NaN 元素不在去重后的数组中了。
方法八、利用 Map 数据结构去重
set() 方法为 Map() 对象添加或更新一个指定了键( key )和值( value )的(新)键值对。
创建一个空 Map 数据结构,遍历需要去重的数组,把数组的每一个元素作为 key 存到 Map 中。由于 Map 中不会出现相同的 key 值,所以最终得到的就是去重后的结果。
/*
方法八: 利用Map数据结构去重
*/
function unique8(arr){
let map = new Map()
let array = []
for(let i = 0;i<arr.length;i++){
// 如果map对象中含有键arr[i]
if(map.has(arr[i])){
// 就用set()方法,将该键对应的value设置为true
map.set(arr[i],true)
}else{
map.set(arr[i],false)
array.push(arr[i])
}
}
return array
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique8(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。
方法九、 利用 reduce() + includes() 去重
/*
方法九:利用reduce+includes
*/
function unique9(arr){
return arr.reduce((prev,curr) => prev.includes(curr) ? prev : [...prev,curr],[])
}
var arr = [1,{},1,'true',true,true,'true',10,10,false,'true',false, 10,undefined,undefined, null,null, NaN, NaN,'NaN', 0, 'a', {},{}]
console.log("原数组的长度是:",arr.length)
console.log(unique9(arr))
打印结果如下:可以发现,原数组的长度是24,去重之后,数组长度是14,其中,重复的 {} 并没有被删除。
总结了这么多数组去重的方法,你学废了吗?