前言

作为前端开发人员,我们最常用的一些数据结构就是 ObjectArray 之类的,毕竟它们使用起来非常的方便。往往有些刚入门的同学都会忽视 SetMap 这两种数据结构的存在,因为能用 setmap 实现的,基本上也可以使用对象或数组实现,而且还更简单。

但是,存在必然合理,当你真正了解 MapSet 之后,你就会发现它们原来时如此美好!

1.基本概念

我们先来了解以下 MapSet 的基本概念,这样才能帮助我们更好的使用。虽然我们通常把这两种数据结构混合着来讲,但事实上它们它们还是有挺大区别的!

1.1 Map(字典)

想要迅速了解一个新的数据结构或 API 是,查看官网是一个不错的选择。Map 在官网上也有解释,我们一起来看下。

官网解释:

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值。

官网的这句话非常精炼,我们从上面这句话中总结如下几个关键词:

  • 键值对
  • 记住插入顺序
  • 任意值作为键

一看到键值对,难免会想到对象。事实确实如此,Map 与我们平常所用的对象非常类似,它是一种类对象的数据结构,所以我们通常称它为 Map 对象。

但是我们可以把它说得更为官方一点:Map 字典。关于程序中字典的概念大家可以下去了解一下。

特点总结:

  • Map 对象这种数据结构和和对象类型,都已键值对的形式存储数据,即 key-vlue 形式。
  • Map 对象存储的数据是有序的,而我们平常使用的对象是无序的,所以通常当我们需要使用对象形式(键值对)存储数据且需要有序时,采用 Map 对象进行存储。
  • Map 对象的键值可以是任意类型,我们平时使用的对象只能使用字符串作为键。

1.2 Set(集合)

Map 类似,我们同样先来看一看官网是怎么解释 Set 这个数据结构的。

官网的解释:

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

Set 的解释比 Map 的解释还要精炼,我们从中提取出几个关键词:

  • 任何类型
  • 唯一值

上面关键词中我们需要重点关注“唯一值”,这说明使用 Set 存储的数据是不会重复的,除此之外,Set 也是一个对象,但是它是一个类数组对象,也就是说它长得像数组,我们通常直接称它为 Set 对象。

当然也可以官方一点的称它:Set 集合。

特点总结:

  • Set 对象是一个类数组对象,它长得就很像数组。
  • Set 对象存储的值是不重复的,所以我们通常使用它来实现数组去重。
  • Set 对象存储的数据不是键值对的形式,而且它可以存储任何类型的数据。

2.基本使用

我们平常使用 Array 或者 Object 的时候,都是直接采用[变量] = [][变量] = {}的形式来进行初始化。而这里我们所讲的 MapSet 数据结构它们都是以构造函数的形式出现的,所以我们通常使用 new Set()或者 new Map()的形式初始化的。

2.1 Map 基本使用

初始化 map 对象:

let myMap = new Map();

初始化 map 时传入数据:

由于 Map 对象是一个构造函数,所以我们在初始化的时候可以传入默认数据的,只不过我们需要注意传入默认数据的格式,它默认接收一个二维数组。

let defaultMap = new Map([['name', '张三'], ['age', 20]]);

打印出来看看结果:

插入数据:

myMap.set('name', '小猪课堂'); // 字符串作为键
myMap.set(12, '会飞的猪'); // number 类型作为键
myMap.set({}, '知乎'); // 对象类型作为键

我们先打印出来看看结果:

获取长度:

我们传统的对象可以通过 Object.key().length 来获取对象长度,而 map 对象自带 size 属性获取对象长度。

let myMapSize = myMap.size;

获取值:

let objKey = {};
myMap.set('name', '小猪课堂'); // 字符串作为键
myMap.set(12, '会飞的猪'); // number 类型作为键
myMap.set(objKey, '知乎'); // 对象类型作为键
let name = myMap.get('name');
let age = myMap.get(12);
let any = myMap.get(objKey);
console.log(name, age, any); // 小猪课堂 会飞的猪 知乎

上段代码中需要注意的是不能使用 myMap.get({})的形式获取数据,因为 objKey!=={}

删除某个值:

myMap.delete('name');

判断某个值是否存在:

myMap.has('name'); // 返回 bool 值

2.2 Set 基本使用

Set对象的使用方式和Map对象的使用方式非常的类似,只不过存储的数据格式不一样罢了。这里需要注意的Set对象存储的不是键值对形式,它只存储了值,没有键,就和数组类似。

初始化Set对象:

let mySet = new Set();

初始化Set对象带有默认值:

Map类似,Set初始化时也可以初始化默认数据。

let defaultSet = new Set(['张三', 12, true]);

一起来看看输出结果:

插入数据:

mySet.add(1);
mySet.add('小猪课堂');

打印结果:

获取长度:

let mySetSize = mySet.size;

获取值:

由于Set对象存储的不是键值对形式,所以未提供get方法获取值,我们通常遍历它获取值:

mySet.forEach((item) => {
  console.log(item)
})

删除某个值:

mySet.delete(1);

判断某个值是否存在:

mySet.has(1); // 返回Boolean值

3.Map和Set区别

如果我们学会了它们两者如何使用,或多或少都知道它们的区别在哪里,我们这里为大家总结一下它们的区别要点:

  • MapSet查找速度都非常快,时间复杂度为O(1),而数组查找的时间复杂度为O(n)
  • Map对象初始化的值为一个二维数组,Set对象初始化的值为一维数组。
  • Map对象和Set对象都不允许键重复(可以将Set对象的键想象成值)。
  • Map对象的键是不能改的,但是值能改,Set对象只能通过迭代器来更改值。

4.使用场景介绍

4.1 Set对象使用场景

数组去重

这是大家很熟悉的一种场景,使用Set对象的唯一性值特性方便的给我们数组去重。

代码如下:

let arr = [1, 2, 3, 4, 5, 6, 3, 2, 5, 3, 2];
console.log([...new Set(arr)]); // [1, 2, 3, 4, 5, 6]

需要注意的是Set对象是一个类数组,我们使用...扩展运算符将一个类数组转化为了一个真正的数组。

4.2 Map对象使用场景

数字类型充当键

代码如下:

let errors = new Map([
  [400, 'InvalidParameter'],
  [404, 'Not found'],
  [500, 'InternalError']
]);
console.log(errors);

输出结果:

我们可以使用Map对象建立一个请求状态码对象字典,因为状态码是数字类型,所以使用Map对象很合适。

除了该场景外,如果需要保证对象的顺序,那么也是可以使用Map对象的。

5.思考点

前面我们说SetMap的插入删除效率为什么很高呢?

这里简单讲一下,更加深入需要大家自己下去好好学习一下数据结构了。

简述原因:

mapset存储的所有元素都是以节点的方式来进行存储的,这种节点结构和链表有点类似。我们都知道链表的特点是插入和删除都非常快,时间复杂度为O(1),两个节点通过指针相连,删除或者增加元素时,我们只是重新更改了指针的指向,不想数组那样,掺入或删除之后需要重新排序。

总结

Set对象和Map对象有很多优点的,比如说性能比较好等等,我们需要一一去体会它们的优缺点。你不如在每次创建数据结构之前想一想:使用Object更好还是Map更好呢?使用Array更好还是Set更好呢? 当然,如果深究SetMap底层原理之后,你会发现它们的实现原理就是红黑树。

到此这篇关于一文搞懂Map与Set的用法和区别的文章就介绍到这了,更多相关Map与Set用法内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

一文搞懂Map与Set的用法和区别解析的更多相关文章

  1. 五分钟理解keep alive用法及原理

    这篇文章主要为大家介绍了keep alive用法及原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  2. Swift 进阶 —— map 和 flatMap的使用

    这篇文章主要介绍了Swift map和flatMap的相关资料,帮助大家更好的理解和使用Swift,感兴趣的朋友可以了解下

  3. DialogFragment运行原理及使用方法详解

    这篇文章主要介绍了DialogFragment运行原理及使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

  4. ES6的Promise用法详解

    本文详细讲解了ES6的Promise用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. React Hook用法示例详解(6个常见hook)

    这篇文章主要介绍了React Hook用法详解(6个常见hook),本文通过实例代码给大家介绍了6个常见hook,需要的朋友可以参考下

  6. react中使用forEach或map两种方式遍历数组

    这篇文章主要介绍了react中使用forEach或map两种方式遍历数组,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. 一文详解Mybatis-plus的介绍与使用

    Mybatis-Plus 是 MyBatis 的一个增强工具,专门针对于传统MyBatis开发中sql需要手动进行映射配置繁琐缺点的一款框架技术。本文将为大家详细讲讲Mybatis-plus的介绍与使用,感兴趣的可以了解一下

  8. Vue中构造数组数据之map和forEach方法实现

    数组操作是前端最重要的数据操作,构造数组数据,又是数组操作中很常见的,本文将梳理下map和forEach方法在Vue项目中的使用,感兴趣的朋友跟随小编一起看看吧

  9. Java Map接口概述和常用方法详解

    现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map接口。本文就来聊聊Map接口概述和常用方法

  10. Java 8 中 Function 接口使用方法介绍

    这篇文章主要介绍了Java 8中 Function接口使用方法介绍,Java8中提供了一个函数式接口Function,这个接口表示对一个参数做一些操作然后返回操作之后的值

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部