JavaScript数组去重的几种方法


Posted in Javascript onApril 07, 2019

前言

有时候我们做项目的时候往往会需要把数组里面一些重复的项去掉,但是原生JS有排序,有筛选等等,但是就是没有数组去重怎么办呢?

这能怎么办,自己手动实现嘛。

数组不像对象和hash有唯一的标志特征(key)。所以,数组去重的核心就是【1】数组内元素互相比较,然后放入新的数组中。【2】参照对象构建一个唯一的特征标志,然后放入新数组中。以下就是依照这种思路产生的方法。【3】数组中含对象的去重方式我采用使用JSON.stringify()将对象转换成JSON字符串进行比较的方式。

1.最基础的去重:双重遍历

双重遍历的核心就是依据【1】,通过拿出一个元素和剩下的元素依次比较,如果全部不相等则证明此元素为唯一。

let a=[{a:1},{b:2},{c:3},{a:1},{d:2}]
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let b=[]
 for(let i=0;i<arr.length;i++){
 let unexit=true
 for(let j=i+1;j<arr.length;j++){
  if(JSON.stringify(arr[i])===JSON.stringify(arr[j])){
  unexit=false
  break
  }
  else{
  unexit=true
  }
 }
 if(unexit){
  b.push(arr[i])
 }
 }
 return b
}

关于数组中存在对象,是采用JSON.stringify()转换成JSON字符串进行的比较,后续不再叙述。双重遍历的缺点是复杂度太高。
上面的代码去重得到的结果的顺序会改变,所以如果想要顺序按照原有顺序,数组在进行去重时建议重新申明一个新的数组(var new=old.reverse() )得到一个新的相反的数组,最后再使用reverse()。之所以新建数组而不是直接取反是因为:reverse()会修改原数组。

2.Array.prototype.sort():相邻元素去重

相邻元素去重的核心在于Array.sort()能够对数组进行排序。这样相等的数组就会在相邻的位置,通过比较相邻的元素就可以起到去重的作用【1】。

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let Arr=arr.sort()
 let b=[]
 for(let i=0;i<Arr.length;i++){
 if(Arr[i]!==Arr[i+1]){
  b.push(Arr[i])
 }
 }
 return b
}

Array.prototype.sort()方法可以使用array.sort((a,b)=>{a.key-b.ky})进行对象的排序,前提是数组中的对象存在相同的key值。

3.Object.keys():存在唯一性

在一个对象里面key值是唯一的,所以通过遍历数组给每个数组一个标志,通过标志去重【2】

let a=[{a:1},{b:2},{c:3},{a:1},{d:2}]
let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let b=[]
 let hash={}
 for(let i=0;i<arr.length;i++){
 if(!hash[JSON.stringify(arr[i])]){
  hash[JSON.stringify(arr[i])]=true
  b.push(arr[i])
 }
 }
 return b
}

4.双重遍历去重改良之:indexOf

双重遍历的思路我们都知道,先拿出一个元素,然后使用循环再次遍历数组去一一比较。如果有一个方式能够让我们不再遍历一遍数组,那么复杂度相对而言会减少一点。

indexOf 方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1。首先我们新建一个空数组(arry),如果:arry.indexOf(数组元素)===-1,那么我们就可以知道arry中不存在元素。

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let b=[]
 for(let i=0;i<arr.length;i++){
 if(b.indexOf(arr[i])==-1){
  b.push(arr[i])
 }
 }
 return b
}

indexOf 方法可返回某个指定的字符串值在字符串中首次出现的位置。所以对象不适用,因为对象转为字符串就都会变成{object,object} ,无法比较。

5.循环遍历之:map()/forEach()

map()和forEach()都可以实现遍历数组。所以以上的方法都可以用map()、forEach()改写。下面我只简单的改写一个,其他的改写方式参照即可。

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let b=[]
 arr.forEach(res=>{
 if(b.indexOf(res)==-1){
  b.push(res)
 }
 })
 return b
}

6.ES6:Set数据结构

Set数据类似于数组,但是成员的值都是唯一的,没有重复的值。它可以接收一个数组,类于:let a=[1,2,3,1,2]  Set(a)=>1,2,3 所以可以使用Set()实现去重。

let c=[1,2,3,4,5,6,1,2,3]
function unique(arr){
 let b=new Set(arr)
 let c=Array.from(b)
 return c
}

Set去重不适用于含对象的数组,因为Set的去重参照的是(===),数组中的元素对象,虽然可能数值相等,但是地址不相等。所以Set无法实现去重。

7.总结

实现数组的去重,要么通过元素对比,要么设置特殊标志识别。元素对比的思路有2种:一种是和原数组一一对比;另一种和新的数组对比。

如果要实现含对象的数组去重,一般使用遍历的方式,包括使用遍历类的方法(map、forEach、reduce等)。像Set、sort等通过改变数组的方式一般是不可行的。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript的事件描述
Sep 08 Javascript
理解Javascript_02_理解undefined和null
Oct 11 Javascript
jquery cookie实现的简单换肤功能适合小网站
Aug 25 Javascript
使用Node.js实现一个简单的FastCGI服务器实例
Jun 09 Javascript
JavaScript设计模式之原型模式(Object.create与prototype)介绍
Dec 28 Javascript
jQuery实现点击后标记当前菜单位置(背景高亮菜单)效果
Aug 22 Javascript
JS递归遍历对象获得Value值方法技巧
Jun 14 Javascript
EasyUI学习之Combobox下拉列表(1)
Dec 29 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
Feb 26 Javascript
浅谈vue中.vue文件解析流程
Apr 24 Javascript
关于js陀螺仪的理解分析
Apr 11 Javascript
jQuery实现高度灵活的表单验证功能示例【无UI】
Apr 30 jQuery
vue表单验证你真的会了吗?vue表单验证(form)validate
Apr 07 #Javascript
js中Generator函数的深入讲解
Apr 07 #Javascript
巧妙运用v-model实现父子组件传值的方法示例
Apr 07 #Javascript
vue路由导航守卫和请求拦截以及基于node的token认证的方法
Apr 07 #Javascript
vue自定义指令directive的使用方法
Apr 07 #Javascript
浅谈express.js框架中间件(middleware)
Apr 07 #Javascript
详解vue中this.$emit()的返回值是什么
Apr 07 #Javascript
You might like
php中通过Ajax如何实现异步文件上传的代码实例
2011/05/07 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
YII框架模块化处理操作示例
2019/04/26 PHP
JavaScript DOM 编程艺术(第2版)读书笔记(JavaScript的最佳实践)
2013/10/01 Javascript
jquery如何实现锚点链接之间的平滑滚动
2013/12/02 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
实例讲解JavaScript中的this指向错误解决方法
2016/06/13 Javascript
AngularJS控制器详解及示例代码
2016/08/16 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
详解Vue.js基于$.ajax获取数据并与组件的data绑定
2017/05/26 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
在vue中封装可复用的组件方法
2018/03/01 Javascript
js中split()方法得到的数组长度问题
2018/07/19 Javascript
详解js常用分割取字符串的方法
2019/05/15 Javascript
微信小程序录音实现功能并上传(使用node解析接收)
2020/02/26 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
2020/04/28 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
python实现的登陆Discuz!论坛通用代码分享
2014/07/11 Python
Python类属性与实例属性用法分析
2015/05/09 Python
Python输出汉字字库及将文字转换为图片的方法
2016/06/04 Python
Python实现点云投影到平面显示
2020/01/18 Python
python第三方库学习笔记
2020/02/07 Python
pandas实现excel中的数据透视表和Vlookup函数功能代码
2020/02/14 Python
python通用读取vcf文件的类(复制粘贴即可用)
2020/02/29 Python
Python自动巡检H3C交换机实现过程解析
2020/08/14 Python
基于CSS3的animation属性实现微信拍一拍动画效果
2020/06/22 HTML / CSS
HTML5新增的8类INPUT输入类型介绍
2015/07/06 HTML / CSS
买卖正宗运动鞋:GOAT
2019/12/06 全球购物
优秀共产党员推荐材料
2014/12/18 职场文书
2016教师年度考核评语大全
2015/12/01 职场文书
公务员廉洁从政心得体会
2016/01/19 职场文书
python基础学习之生成器与文件系统知识总结
2021/05/25 Python
Python基于百度AI实现抓取表情包
2021/06/27 Python
spring boot中nativeQuery的用法
2021/07/26 Java/Android