js实现数组去重的方式(7种)
JS数组去重的方式
例:将下面数组去除重复元素(以多种数据类型为例)
const arr = [1, 2, 2, 'abc', 'abc', true, true, false, false, undefined, undefined, NaN, NaN]
1.利用Set()+Array.from()
Set对象:是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即Set中的元素是唯一的。Array.from()方法:对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
const result = Array.from(new Set(arr))
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
注意:以上去方式对NaN和undefined类型去重也是有效的,是因为NaN和undefined都可以被存储在Set中, NaN之间被视为相同的值(尽管在js中:NaN !== NaN)。
2.利用两层循环+数组的splice方法
通过两层循环对数组元素进行逐一比较,然后通过splice方法来删除重复的元素。此方法对NaN是无法进行去重的,因为进行比较时
NaN !== NaN。
function removeDuplicate(arr) {
let len = arr.length
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
if (arr[i] === arr[j]) {
arr.splice(j, 1)
len-- // 减少循环次数提高性能
j-- // 保证j的值自加后不变
}
}
}
return arr
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]
3.利用数组的indexOf方法
新建一个空数组,遍历需要去重的数组,将数组元素存入新数组中,存放前判断数组中是否已经含有当前元素,没有则存入。此方法也无法对
NaN去重。
indexOf()方法:返回调用它的String对象中第一次出现的指定值的索引,从fromIndex处进行搜索。如果未找到该值,则返回 -1。
function removeDuplicate(arr) {
const newArr = []
arr.forEach(item => {
if (newArr.indexOf(item) === -1) {
newArr.push(item)
}
})
return newArr // 返回一个新数组
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN, NaN ]
4.利用数组的includes方法
此方法逻辑与indexOf方法去重异曲同工,只是用includes方法来判断是否包含重复元素。
includes()方法:用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false。
function removeDuplicate(arr) {
const newArr = []
arr.forEach(item => {
if (!newArr.includes(item)) {
newArr.push(item)
}
})
return newArr
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
注意:为什么includes能够检测到数组中包含NaN,其涉及到includes底层的实现。如下图为includes实现的部分代码,在进行判断是否包含某元素时会调用sameValueZero方法进行比较,如果为NaN,则会使用isNaN()进行转化。
具体实现可参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

简单测试includes()对NaN的判断:
const testArr = [1, 'a', NaN]
console.log(testArr.includes(NaN)) // true
5.利用数组的filter()+indexOf()
filter方法会对满足条件的元素存放到一个新数组中,结合indexOf方法进行判断。
filter()方法:会创建一个新数组,其包含通过所提供函数实现的测试的所有元素。
function removeDuplicate(arr) {
return arr.filter((item, index) => {
return arr.indexOf(item) === index
})
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined ]
注意:这里的输出结果中不包含NaN,是因为indexOf()无法对NaN进行判断,即arr.indexOf(item) === index返回结果为false。测试如下:
const testArr = [1, 'a', NaN]
console.log(testArr.indexOf(NaN)) // -1
6.利用Map()
Map对象是JavaScript提供的一种数据结构,结构为键值对形式,将数组元素作为map的键存入,然后结合
has()和set()方法判断键是否重复。
Map对象:用于保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。
function removeDuplicate(arr) {
const map = new Map()
const newArr = []
arr.forEach(item => {
if (!map.has(item)) { // has()用于判断map是否包为item的属性值
map.set(item, true) // 使用set()将item设置到map中,并设置其属性值为true
newArr.push(item)
}
})
return newArr
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
注意:使用Map()也可对NaN去重,原因是Map进行判断时认为NaN是与NaN相等的,剩下所有其它的值是根据 === 运算符的结果判断是否相等。
7.利用对象
其实现思想和
Map()是差不多的,主要是利用了对象的属性名不可重复这一特性。
function removeDuplicate(arr) {
const newArr = []
const obj = {}
arr.forEach(item => {
if (!obj[item]) {
newArr.push(item)
obj[item] = true
}
})
return newArr
}
const result = removeDuplicate(arr)
console.log(result) // [ 1, 2, 'abc', true, false, undefined, NaN ]
js实现数组去重的方式(7种)的更多相关文章
- js中数组去重的几种方法
js中数组去重的几种方法 1.遍历数组,一一比较,比较到相同的就删除后面的 function unique(arr){ ...
- Js对于数组去重提高效率一些心得
最近在找工作,好几次面试都问过数组去重的问题.虽然问的都不一样,但是核心思想是没有变的. 第一种是比较常规的方法 思路: 构建一个新的数组存放结果 for循环中每次从原数组中取出一个元素,用这个元素循 ...
- JS实现数组去重方法大总结
js数组根据对象中的元素去重: var arr2 = [ { name: "name1", num: "1" }, { name: "name2&qu ...
- JavaScript数组去重—ES6的两种方式
说明 JavaScript数组去重这个问题,经常出现在面试题中,以前也写过一篇数组去重的文章,(JavaScript 数组去重的多种方法原理详解)但感觉代码还是有点不够简单,今天和大家再说两种方法,代 ...
- JavaScript常见的五种数组去重的方式
▓▓▓▓▓▓ 大致介绍 JavaScript的数组去重问题在许多面试中都会遇到,现在做个总结 先来建立一个数组 var arr = [1,2,3,3,2,'我','我',34,'我的',NaN,NaN ...
- js引用类型数组去重-对象标记法
前言 Js数组去重已经有很多种实现方式:包括逐个检索对比(使用Array.property.indexOf),先排序后对比,使用hash表,利用ES6中的Set()等.这些数组去重办法中速度最快的是h ...
- JS实现数组去重方法整理
前言 我们先来看下面的例子,当然来源与网络,地址<删除数组中多个不连续的数组元素的正确姿势> 我们现在将数组中所有的‘ a’ 元素删除: var arr = ['a', 'a', 'b', ...
- js对数组去重的完整版
数组去重是很常见的一个需求,而各种各样的姿势也很多,常见的如indexOf,或者hash,但是他们还是有缺陷,这里我查了一些资料做补充. 一般方式 //一般方法->使用indexOf Array ...
- js对数组去重的方法总结-(2019-1)
最近待业在家,系统地学习了一套js的课程.虽然工作时间真的比较长了,但有些东西只局限在知其然而不知其所以然的程度上,有些知识点通过“血和泪”的经验积累下来,也只是记了结果并没有深究,所以每次听完课都有 ...
随机推荐
- 第05章 MySQL排序与分页
第05章 MySQL排序与分页 1. 排序数据 1.1 排序规则 使用 ORDER BY 子句排序 ASC(ascend): 升序 DESC(descend):降序 ORDER BY 子句在SELEC ...
- Spring MVC应用
Spring MVC简介 1.1 经典三层结构 在JavaEE开发中,几乎全部都是基于B/S架构的开发.那么在B/S架构中,系统标准的三层架构包括:表现层.业务层.持久层.三层架构在我们的实际开发中使 ...
- @Value设置默认值
使用@Value注解将变量进行自动注入的时候,经常会出现的一个问题就是我们可能会由于在配置参数中忘记设置该参数造成整个项目报错,其实我们可以通过给被@Value注解作用的变量进行注入的时候如果没有找到 ...
- JAVA特点及安装卸载
C语言特点 1972 贴近硬件,运行速度快,效率高 操作系统,数据库,网络系统,编译器 指针和内存管理 C++语言特点 1982 面向对象 兼容C 图形领域,游戏等 Java语言特点 简单性 面向对象 ...
- Go语言核心36讲(Go语言实战与应用十七)--学习笔记
39 | bytes包与字节串操作(下) 在上一篇文章中,我们分享了bytes.Buffer中已读计数的大致功用,并围绕着这个问题做了解析,下面我们来进行相关的知识扩展. 知识扩展 问题 1:byte ...
- SpringCloud微服务实战——搭建企业级开发框架(二十六):自定义扩展OAuth2实现短信验证码登录
现在手机验证码登录似乎是每个网站必备的功能,OAuth2支持扩展自定义授权模式,前面介绍了如何在系统集成短信通知服务,这里我们进行OAuth2的授权模式自定义扩展,使系统支持短信验证码登录. 1.在g ...
- 详解在Linux中安装配置MySQL
最近在整理自己私人服务器上的各种阿猫阿狗,正好就顺手详细记录一下清理之后重装的步骤,今天先写点数据库的内容,关于在Linux中安装配置MySQL 安装环境 CentOS7 + MySQL5.7 下载安 ...
- expr判断是否为整数
判断一个变量值或字符串是否为整数 原理:利用expr计算时变量或字符串必须为整数的规则,把变量和一个整数(非零) 相加,判断命令返回是否为0,0--成功为整数 #!/bin/bash expr $1 ...
- hbase调优
@ 目录 一.phoenix调优 1.建立索引超时,查询超时 2.预分区 hbase shell预分区 phoenix预分区 3.在创建表的时候指定salting. 4.二级索引 建立行键与列值的映射 ...
- 学习java的第十天
一.今日收获 1.java完全学习手册第二章2.9程序流程控制中的选择结构与顺序结构的例题 2.观看哔哩哔哩上的教学视频 二.今日问题 1.例题的问题不大,需要注意大小写,新的语句记忆不牢 2.哔哩哔 ...