自从有了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))
}
 function unique(arr) {
      return [...new Set(arr.map(e => JSON.stringify(e)))].map(e => JSON.parse(e))
  }
// 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数据结构对对象数组去重简单实现的更多相关文章

  1. js ES6 Set和Map数据结构详解

    这篇文章主要介绍了ES6学习笔记之Set和Map数据结构,结合实例形式详细分析了ECMAScript中基本数据结构Set和Map的常用属性与方法的功能.用法及相关注意事项,需要的朋友可以参考下   本 ...

  2. es6 Set 和Map 数据结构

    ES6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 本身是一个数据结构,用来生成Set 数据结构. const s = new Set(); [2,3,5,4 ...

  3. JavaScript中好用的对象数组去重

    对象数组去重 Demo数据如下: var items= [{ "specItems": [{ "id": "966480614728069122&qu ...

  4. ES6新数据结构Set让数组去重

    function unique(array){ return Array.from(new Set(array)); } var arr = ['aa','bb','cc','',1,0,'1',1, ...

  5. es6入门7--Set Map数据结构

    本文作为ES6入门第十三章的学习整理笔记,可能会包含少部分个人的理解推测,若想阅读更详细的介绍,还请阅读原文ES6入门 一.set数据结构 1.set不接受重复值 ES6新增了Set构造函数用于创建s ...

  6. js 对象数组去重

    var arr = [{ "name": "ZYTX", "age": "Y13xG_4wQnOWK1QwJLgg11d0pS4h ...

  7. JavaScript中对象数组去重方法

    在一次对后端返回的对象数组的操作时想通过indexOf()或者includes()的方法来实现对对象数组的去重但是行不通,因为用indexOf()返回的都是-1,一下记录两种对象数组(更具指定属性)去 ...

  8. vue中对象数组去重

    其实很简单,一般的数组去重可以直接用 new Set() 方法即可,但是数组对象的话,比较复杂,不能直接用,我们可以采取间接的方法来去重 unique(arr) { const res = new M ...

  9. ES6深入浅出-10 ES6新增的数据类型-2.Set与数组去重

    一种新的数据类型,它是对象的一种,Set,很像数组,又不是数组. Set 类型 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refe ...

随机推荐

  1. Leetcode874.Walking Robot Simulation模拟行走的机器人

    机器人在一个无限大小的网格上行走,从点 (0, 0) 处开始出发,面向北方.该机器人可以接收以下三种类型的命令: -2:向左转 90 度 -1:向右转 90 度 1 <= x <= 9:向 ...

  2. PHP学习(数据类型)

    PHP中,支持8种原始类型,其中包括四种标量类型.两种复合类型和两种特殊类型.PHP是一门松散类型的语言,不必向PHP声明变量的数据类型,PHP会自动把变量转换为自动的数据类型,一定程度降低了学习PH ...

  3. 介绍(javascript调试)

    Chrome developer tool Chrome浏览器得益于其优秀的V8解释器,javascript执行速度和内存占有率表现非常优秀.对于html+css+javascript前台技术的学习或 ...

  4. Directx11教程(13) D3D11管线(1)

    原文:Directx11教程(13) D3D11管线(1)       从本篇教程开始,我们暂停代码的学习,先来了解一下D3D11的管线,这些管线不涉及具体的硬件,而是着重于理解能够支持D3D11的管 ...

  5. oracle如何回收空间?

    ALTER TABLE 名称 DEALLOCATE UNUSED [KEEP 4[M|K]] 1.当空间分配过大时,可以使用本命令 2.如果没有加KEEP,回收到水线 3.如果水线<MINEXT ...

  6. Leetcode728.Self Dividing Numbers自除数

    自除数 是指可以被它包含的每一位数除尽的数. 例如,128 是一个自除数,因为 128 % 1 == 0,128 % 2 == 0,128 % 8 == 0. 还有,自除数不允许包含 0 . 给定上边 ...

  7. More Effective C++: 01基础议题

    01:仔细区别 pointers 和 references 1:没有所谓的null reference,但是可以将 pointer 设为null.由于 reference 一定得代表某个对象,C++ ...

  8. iOS 内存管理arc

    http://www.tekuba.net/program/346/ ios自动释放池(autoreleasepool #import <Foundation/Foundation.h> ...

  9. selenium 图片上传

    WebElement  file = driver.findElement(By.name("filename")); 给此元素设置值:file.sendKeys("E: ...

  10. CSS文本超过两行用省略号代替

    1.只显示一行,超出部分用省略号 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 2.只显示两行(或多行),超出部分用省 ...