{{format('0')}} {{format('187')}} {{format('3490')}}

【前端】浅谈数组去重 [ 前端 ]

晚安月亮 文章 正文

挣钱给咖喱买最好吃的罐罐
分享

椰奶冻

{{nature("2024-02-18 15:11:48")}}更新

1、Set

原理:Set类似于数组,但是成员的值都是唯一的,接受一个数组或类数组作为参数。代码最少但是无法去掉{}空对象。

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = Array.from(new Set(arr))
console.log(result)  // (11) [1, 2, "true", true, undefined, null, NaN, {}, {}, {a:1}, {a:1}]

2、indexOf() + 循环

原理:创建一个空数组来判断是否存在,不存在则push到新数组中

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = [];
for (let i = 0; i < arr.length; i++) {
if (result.indexOf(arr[i]) === -1) { // indexOf() === -1表示没找到
result.push(arr[i])
}
}
console.log(result) // (12) [1, 2, "true", true, undefined, null, NaN, NaN, {}, {}, {a:1}, {a:1}]

3、for+splice() 循环去重

原理:splice()方法可以实现删除,并且改变原数组,然后通过双重循环对比实现删除。NaN和{}没有去重

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
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)  //splice() 第一个参数表示从哪个元素开始,第二个表示要删除元素个数
}
}
}
console.log(arr) // (12) [1, 2, "true", true, undefined, null, NaN, NaN, {}, {}, {a:1}, {a:1}]

4、sort()+相邻元素对比

原理:先用sort()方法把数组排序,这样相同的元素就在一起了,然后通过前后对比,如果不一样则push到新数组中。NaN、{}没有去重

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
arr = arr.sort();
let result = [arr[0]]
for (let i = 1; i < arr.length; i++) {
    if (arr[i] !== arr[i-1]) { // 后一个与前面对比
result.push(arr[i])
}
}
console.log(result) // (12) [1, 2, NaN, NaN, {}, {}, {a:1}, {a:1}, null, "true", true, undefined]

5、对象属性判断

原理:利用对象属性不能相同去重,我们可构造一个空对象,让后把数组元素变为对象属性,判断是否属性存在,如果不存在则push到新数组中。缺点是对象属性会隐式转换为字符串,如true和‘true’会判断为相同

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = [], obj = {};
for (let i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
result.push(arr[i])
obj[arr[i]] = 1;
}
}
console.log(result) // (7) [1, 2, "true", undefined, null, NaN, {}]

6、includes() + 循环

原理:类似于indexOf()方法,只是此方法返回布尔值,判断如果不在则push到新数组中。{}没有去重

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = [];
for (let i = 0; i < arr.length; i++) {
if (!result.includes(arr[i])) {  // 如果不存在
result.push(arr[i])
}
}
console.log(result) // (11) [1, 2, "true", true, undefined, null, NaN, {}, {}, {a:1}, {a:1}]

7、filter + indexOf()

原理:利用indexOf()方法判断元素索引位置是否相同,如果不相同则说明已存在,则过滤掉。{}没有去重

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = arr.filter((item, index, arr) => {
return arr.indexOf(item) === index // 判断每个值得索引位置
})
console.log(result) // (10) [1, 2, "true", true, undefined, null, {}, {}, {a:1}, {a:1}]

8、Map 键值对集合

原理:类似于对象的键值对集合,利用键不能重复的特点,优点是键可以是如何数据类型,可以说是对象的优化。NaN,{}没有去重

let arr = [1, 1, 2, "true", true, true, undefined, undefined, null, null, NaN, NaN, {}, {}, {a:1}, {a:1}]
let result = [], map = new Map();
for (let i = 0; i < arr.length; i++) {
if (!map.has(arr[i])) {
result.push(arr[i])
map.set(arr[i], 1)
}
}
console.log(result) // (11) [1, 2, "true", true, undefined, null, NaN, {}, {}, {a:1}, {a:1}]

总结:

 **其实上面的方法基本上都是利用循环,只是判断元素的方法略有区别。注意的是,基本上所有的方法比较值都是通过==来判断的,但是NaN是个特列,NaN==NaN返回的也是true,所以去重数据最好是不要有NaN。也有一些方法可以比较NaN,比如Set、Map、includes()等**

评论 0
0
{{userInfo.data?.nickname}}
{{userInfo.data?.email}}
TOP 2
【笔经】数字马力前端笔试-22应届

{{nature('2022-06-23 23:10:58')}} {{format('1477')}}人已阅读

TOP 3
【React】React组件卸载生命周期、路由跳转、页面关闭(刷新)拦截提示

{{nature('2023-02-03 16:12:08')}} {{format('1397')}}人已阅读

TOP 4
【前端】npm/yarn报错:getaddrinfo ENOTFOUND registry.nlark.com

{{nature('2024-05-29 15:14:38')}} {{format('1025')}}人已阅读

TOP 5
【前端】jspdf+dom-to-image生成多页A4pdf加防截断处理

{{nature('2024-05-24 15:20:21')}} {{format('905')}}人已阅读

目录

标签云

JavaScript

一言

# {{hitokoto.data.from || '来自'}} #
{{hitokoto.data.hitokoto || '内容'}}
作者:{{hitokoto.data.from_who || '作者'}}
自定义UI
配色方案

侧边栏