ES6 set和map数据结构对对象数组去重简单实现
自从有了es6的set数据结构,数组的去重可以简单用一行代码实现,比如下面的方式
let arr = [1, 2, 2, 3, 4]
function unique (arr) {
return [...new Set(arr)]
}
console.log(unique(arr)) // [1, 2, 3, 4]
但是当数组的项不再是简单的数据类型时,比如是对象时,这种方法就会导致错误,比如下面的结果
let arr = [
{ name: 'a', num: 1},
{ name: 'b', num: 1},
{ name: 'c', num: 1},
{ name: 'd', num: 1},
{ name: 'a', num: 1},
{ name: 'a', num: 1},
{ name: 'a', num: 1}
]
function unique (arr) {
return [...new Set(arr)]
}
console.log(unique(arr)) // 结果为原数组,有兴趣可以复制代码试一下
其中的原因是因为set数据结构认为对象永不相等,即使是两个空对象,在set结构内部也是不等的
基于以上原因,利用map和set结构封装了一种对对象数组去重的简单方法,其实他们本质都是一样的,只是使用sjon.stringfy()和json.parse()会影响性能,具体如下
// ES6对象数组所有属性去重,筛选每个数组项的字符
function unique(arr) {
const map = new Map()
return arr.filter( item => !map.has(JSON.stringify(item)) && map.set(JSON.stringify(item), 1))
}
// ES6根据一维对象数组某个属性去重且该属性的值为简单数据类型,比较实用的一种的方法,也基本没有什么性能影响
function unique(arr, key) {
const map = new Map()
return arr.filter((item) => !map.has(item[key] + '') && map.set(item[key] + '', 1))
}
网上有朋友设计了一种更简单的方法,主要是对map数据结构的键理解得不一样,其他没什么区别,代码如下
// ES6对象数组所有属性去重,筛选每个数组项的字符
function unique2(arr) {
const map = new Map()
return arr.filter( item => !map.has(item) && map.set(item, 1))
}
实际试了一下,发现没有起到去重的效果,不知道具体原因是什么,我的理解是当用item指代数组中的每一项的对象的时候,item保存的是对对象的指针,即栈中的地址,并不是对象本身,所以每一个item的地址是不一样的,尽管他们都指向同一个堆数据,所以map认为每一个item并不相等,当然就起不到去重的效果。如果有更正确和深入的理解欢迎讨论哈
ES6 set和map数据结构对对象数组去重简单实现的更多相关文章
- js ES6 Set和Map数据结构详解
这篇文章主要介绍了ES6学习笔记之Set和Map数据结构,结合实例形式详细分析了ECMAScript中基本数据结构Set和Map的常用属性与方法的功能.用法及相关注意事项,需要的朋友可以参考下 本 ...
- es6 Set 和Map 数据结构
ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个数据结构,用来生成Set 数据结构. const s = new Set(); [2,3,5,4 ...
- JavaScript中好用的对象数组去重
对象数组去重 Demo数据如下: var items= [{ "specItems": [{ "id": "966480614728069122&qu ...
- ES6新数据结构Set让数组去重
function unique(array){ return Array.from(new Set(array)); } var arr = ['aa','bb','cc','',1,0,'1',1, ...
- es6入门7--Set Map数据结构
本文作为ES6入门第十三章的学习整理笔记,可能会包含少部分个人的理解推测,若想阅读更详细的介绍,还请阅读原文ES6入门 一.set数据结构 1.set不接受重复值 ES6新增了Set构造函数用于创建s ...
- js 对象数组去重
var arr = [{ "name": "ZYTX", "age": "Y13xG_4wQnOWK1QwJLgg11d0pS4h ...
- JavaScript中对象数组去重方法
在一次对后端返回的对象数组的操作时想通过indexOf()或者includes()的方法来实现对对象数组的去重但是行不通,因为用indexOf()返回的都是-1,一下记录两种对象数组(更具指定属性)去 ...
- vue中对象数组去重
其实很简单,一般的数组去重可以直接用 new Set() 方法即可,但是数组对象的话,比较复杂,不能直接用,我们可以采取间接的方法来去重 unique(arr) { const res = new M ...
- ES6深入浅出-10 ES6新增的数据类型-2.Set与数组去重
一种新的数据类型,它是对象的一种,Set,很像数组,又不是数组. Set 类型 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refe ...
随机推荐
- 模板内置函数(HTML)
模板内置函数 注意:1.html书写避免多余的空格,否则可能无法被识别 2.模板是用来渲染的不要用来处理逻辑 后台ctime=datetime.datatime.now() {{ctime|date: ...
- oralce系统触发器
系统事件是指基于oracle事件(例如logon.logoff和startup.shutdown)所建立的触发器,通过使用系统事件触发器,提供了跟踪系统或是数据库变化机制.下面介绍使用的系统事件属性函 ...
- 中文乱码在java中URLEncoder.encode方法要调用两次解决
中文乱码在java中URLEncoder.encode方法要调用两次解决 一.场景: 1.我在客户端要通过get方式调用服务器端的url,将中文参数做utf-8编码,需要在js中两次的进行编码,服务器 ...
- phpexcel使用说明4
<div class="postBody"> <div id="cnblogs_post_body"><p>PHPExcel ...
- linux下安装使用MySQL 以及 python mysqldb 遇到的问题
一.安装mysql sudo apt-get install mysql-client-core-5.5 然后会出现: ERROR 2002 (HY000): Can't connect to loc ...
- Docker镜像部分详解
拉取镜像: docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] Docker 镜像仓库地址:地址的格式一般是 [:端口号].默认地址是 Docke ...
- Atcoder Tenka1 Programmer Contest C C - 4/N
http://tenka1-2017.contest.atcoder.jp/tasks/tenka1_2017_c 我怀疑我是不是智障.... 本来一直的想法是能不能构造出答案,把N按奇偶分,偶数好办 ...
- find 使用搜集
find:-atime +n/-n:表示访问或执行时间大于或小于n天的文件-ctime +n/-n:表示写入.更改inode属性的时间大于或小于n天的文件-mtime +n/-n:表示写入时间大于或小 ...
- WPF Canvas实现进度条
原文:WPF Canvas实现进度条 先看效果图: 思路: 一个Canvas做背景,一个Canvas用来显示进度,图片放在显示进度的Canvas中,靠右设置为图片本身宽度一半的距离,视觉上实现以图片中 ...
- 走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相
背景 闲鱼客户端的flutter页面已经服务上亿级用户,这个时候Flutter页面的用户体验尤其重要,完善Flutter性能稳定性监控体系,可以及早发现线上性能问题,也可以作为用户体验提升的衡量标准. ...