[ES6] Map Set

[ES6] Map & Set

  • Map
    • Map 与 Object 区别
    • Map 的初始化
      • 键值是对象与函数的情况
      • 键值是 NaN
      • 方法的使用
    • Map 的迭代
    • Map 对象操作
      • Map 与数组的转化
      • Map 的克隆
      • Map 的合并
  • Set 对象
    • Set 中的特殊值
    • Set 的初始化
    • 类型转换
      • Array 与 Set 互相转换
      • String 转 Set
    • Set 方法
    • Set 迭代
    • Set 对象作用
      • 数组去重
      • Set 的合并-并集
      • 交集
      • 差集

Map

Map 与 Object 区别

Map 是用于保存键值对,似乎与 Object 非常类似

  • 键值
    Object 的键只能是字符串或者 Symbols(ES6 新增基础类型),但 Map 的键可以是任意值–包括对象、函数等
  • 键值顺序
    Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是
  • 键值个数
    Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动或其它自定义方法计算

并且 Object 都有原型,原型链上的键名(保留键)有可能和你在对象上的设置的键名产生冲突。

Map 的初始化

Map 的设置与应用也可查看Typescript 的 Map 对象,这部分简单介绍了键是字符串的 Map 的用法

//方法1
let myMap = new Map();
// 设置 Map 对象
myMap.set("key1", value1);
myMap.set("key2", value2);
myMap.set("key3", value3);

//方法2
let myMap = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);

键值是对象与函数的情况

用变量表示对象与函数,应用 Map 的情况与字符串是一样的,但是有一些特殊情况需要注意:

let myMap = new Map();
let keyObj = {};
myMap.set(keyObj, "和键 keyObj 关联的值");
myMap.get(keyObj); // "和键 keyObj 关联的值"
myMap.get({}); // undefined, 因为 keyObj !== {}

函数也类似,所以复杂类型的键值并不是形式看着一样就是同一个值,必须是指针指向的是同一个地址的键值才能获取到对应值

键值是 NaN

let myMap = new Map();
myMap.set(NaN, "Key is NaN");

myMap.get(NaN); // "Key is NaN"

let otherNaN = Number("foo"); //Number(undefined)
myMap.get(otherNaN); // "Key is NaN"

我们知道 NAN 是和任意值都不相等的,甚至它自己,但是在上述的测试中发现 Map 中,Map 认为 NaN 作为键值的时候被认为是相等

并且当 Number()的参数是 string 类型与 undefined 的时候,myMap.get(otherNaN)的结果也和 NaN 是相同的

其它的情况,包括myMap.get(undefined),myMap.get(null)直接获取,设置otherNaN其它可能与 NaN 相等的情况均是 undefined

let otherNaN = Number(true); //Number(false)
myMap.get(undefined); //undefined
myMap.get(null); //undefined
myMap.get(otherNaN); //undefined

## Map  方法

Map  方法描述
map.clear()移除  Map  对象的所有键/值对
map.set()设置键值对,返回 Map  对象
map.get()返回键对应的值,如果不存在,则返回  undefined
map.has()返回布尔值,用于判断  Map  中是否包含键对应的值
map.delete()删除键对应元素,成功返回  true,失败或不存在返回 false
map.size返回  Map  对象键/值对的数量
map.keys()返回  Iterator  对象,  包含了  Map  对象中每个元素的键
map.values()返回 Iterator 对象,包含了 Map 对象中每个元素的值
map.entries()返回键值对数组迭代对象. map.entries().next().value 可返回每个值

方法的使用

let nameSiteMapping = new Map();

// 设置 Map 对象
nameSiteMapping.set("Google", 1);
nameSiteMapping.set("Runoob", 2);
nameSiteMapping.set("Taobao", 3);

// 获取键对应的值
console.log(nameSiteMapping.get("Runoob")); // 2

// 判断 Map 中是否包含键对应的值
console.log(nameSiteMapping.has("Taobao")); // true
console.log(nameSiteMapping.has("Zhihu")); // false

// 返回 Map 对象键/值对的数量
console.log(nameSiteMapping.size); // 3

// 删除 Runoob
console.log(nameSiteMapping.delete("Runoob")); // true
console.log(nameSiteMapping);
// 移除 Map 对象的所有键/值对
nameSiteMapping.clear(); // 清除 Map
console.log(nameSiteMapping);

Map 的迭代

Map 对象中的元素是按顺序插入的,迭代 Map 对象也是按顺序迭代,每一次迭代返回 [key, value] 数组

let nameSiteMapping = new Map();

nameSiteMapping.set("Google", 1);
nameSiteMapping.set("Runoob", 2);
nameSiteMapping.set("Taobao", 3);

// 迭代 Map 中的 key
for (let key of nameSiteMapping.keys()) {
  console.log(key);
}

// 迭代 Map 中的 value
for (let value of nameSiteMapping.values()) {
  console.log(value);
}

// 迭代 Map 中的 key => value
for (let entry of nameSiteMapping.entries()) {
  console.log(entry[0], entry[1]);
}

// 使用对象解析
for (let [key, value] of nameSiteMapping) {
  console.log(key, value);
}

nameSiteMapping.forEach(function (value, key) {
  console.log(key + " = " + value);
}, nameSiteMapping);

forEach 方法的第二个参数,表示绑定处理函数内部的 this 对象,如果省略则表示是调用对象本身,上述可省略第二个参数

Map 对象操作

Map 与数组的转化

let array = [
  ["key1", "value1"],
  ["key2", "value2"]
];
// Map 构造函数可以将 二维 键值对数组转换成Map 对象
let myMap = new Map(array);
// 使用 Array.from 函数可以将Map 对象转换成二维键值对数组
let outArray = Array.from(myMap);

Map 的克隆

Map 的克隆是 Map 对象构造函数生成实例,迭代出新的对象

let myMap1 = new Map([
  ["key1", "value1"],
  ["key2", "value2"]
]);
let myMap2 = new Map(myMap1);
console.log(myMap1 === myMap2); //  false

Map 的合并

REST 运算符合构建新的数组

合并两个 Map 对象时,如果有重复的键值,则后面的会覆盖前面的

let first = new Map([
  [1, "one"],
  [2, "two"],
  [3, "three"]
]);
let second = new Map([
  [1, "uno"],
  [2, "dos"]
]);
// 对应值即 uno,dos,three
let merged = new Map([...first, ...second]);

Set 对象

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

Set 结构的键名就是键值

Set 中的特殊值

Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等,恒等则不能同时存在。有几个特殊值需要特殊对待:

  • +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
  • undefined 与 undefined 是恒等的,所以不重复;
  • NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个 NaN,不重复。

Set 的初始化

let mySet = new Set(); //Set(0) {}
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5} 这里体现了值的唯一性
mySet.add("some text"); // Set(3) {1, 5, "some text"} 这里体现了类型的多样性
let o = { a: 1, b: 2 };
mySet.add(o); // Set(5) {1, 5, "some text", {…}}
mySet.add({ a: 1, b: 2 }); // Set(5) {1, 5, "some text", {…}, {…}}
// 这里体现了对象之间引用不同不恒等,即使值相同,内存地址并不相同

以上是先创建空集合,使用了 add 方法设置 Set 的值

new Set()通过直接传递参数初始化的方式 请查看下面的类型转换

类型转换

Array 与 Set 互相转换

let mySet = new Set(["value1", "value2", "value3"]); // Array 转 Set
console.log(mySet); //Set(3) { 'value1', 'value2', 'value3' }
let myArray = [...mySet]; // 用...操作符,将 Set 转 Array

String 转 Set

let mySet = new Set("hello"); // Set(4) {"h", "e", "l", "o"}
// 注:Set 中 toString 方法不能将 Set 转换成 String

Set 方法

Set 方法描述
set.clear()清空 set 实例,无返回值
set.add()添加 set 成员
set.has()Set 是否包含成员,包含返回 true
set.delete()删除成员,成功返回  true,其它返回 false
set.size返回  Map  对象键/值对的数量
set.keys()返回键名的  Iterator  对象
set.values()返回键值的 Iterator 对象
set.entries()返回键值对迭代对象
set.forEach()回调函数遍历每个成员

Set 迭代

Set 结构的键名就是键值,因此两者相同

let set = new Set(["value1", "value2", "value3"]);

for (let item of set.keys()) {
  console.log(item);
}

for (let item of set.values()) {
  console.log(item);
}

for (let item of set.entries()) {
  console.log(item);
}

set.forEach((value, key) => console.log(value));
//打印
//value1
//value2
//value3

Set 对象作用

数组去重

let mySet = new Set([1, 2, 3, 4, 4]);
[...mySet]; // [1, 2, 3, 4]

利用 Set 值的唯一性

Set 的合并-并集

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let union = new Set([...a, ...b]); // {1, 2, 3, 4}

交集

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let intersect = new Set([...a].filter((x) => b.has(x))); // {2, 3}

差集

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let difference = new Set([...a].filter((x) => !b.has(x))); // {1}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/13322.html

如若内容造成侵权/违法违规/事实不符,请联系三亩地网进行投诉反馈,一经查实,立即删除!

相关文章

一文搞懂Session和JWT登录认证

前言 目前在开发的小组结课项目中用到了JWT认证,简单分享一下,并看看与Session认证的异同。 登录认证(Authentication)的概念非常简单,就是通过一定手段对用户的身份进行确认。 我们都知道 HTTP 是无状态的&#xf…

强化学习技巧

此软件包处于维护模式,请使用Stable-Baselines3 (SB3)获取最新版本。您可以在 SB3 文档中找到迁移指南。 本节的目的是帮助您进行强化学习实验。它涵盖了有关 RL 的一般建议(从哪里开始、选择哪种算法、如何评估算法等),以及使用自…

【Linux】System V 共享内存、消息队列、信号量

🍎作者:阿润菜菜 📖专栏:Linux系统编程 system V共享内存介绍 System V 共享内存是一种进程间通信的机制,它允许多个进程共享一块物理内存区域(称为“段”)。System V 共享内存的优点是效率高&…

OTG是什么意思?

OTG是什么意思? OTG是怎么样实现的? TYPE-C接口的手机如何实现同时充电OTG功能? OTG是什么意思? OTG是On-The-Go的缩写,是一项新兴技术,主要应用于不同的设备或移动设备间的联接,进行数据交…

基于遥感的自然生态环境检测——实验三:生态因子提取

实验三:生态因子提取 一、实验目标 生态因子生成;生态因子归一化;生态环境评价 二、实验内容 根据经过大气校正后的影像生产土地覆盖指数、土壤指数以及坡度等,对土地覆盖指数、土壤指数以及坡度进行密度分割归一化&#xff1…

“SCSA-T学习导图+”系列:下一代防火墙

本期引言: 近年来,随着数字化业务带给我们高效和便捷的同时,信息暴露面的增加、网络边界的模糊化以及黑客攻击的产业化,使得网络安全事件相较以往成指数级增加。传统防火墙基于五元组的方式对进出网络的数据流量进行访问控制&…

JavaScript(JS)-1.JS基础知识

1.JavaScript概念 (1)JavaScript是一门跨平台,面向对象的脚本语言,来控制网页行为的,它能使网页可交互 (2)W3C标准:网页主要由三部分组成 ①结构:HTML负责网页的基本结构(页面元素和内容)。 …

【Linux网络服务】Linux网络设置

一、查看网络配置 1.1ifconfig 1.2ip a 1.3什么是mtu 最大传输单元MTU,是指网络能够传输的最大数据包大小,以字节为单位。MTU的大小决定了发送端一次能够发送报文的最大字节数。如果MTU超过了接收端所能够承受的最大值,或者是超过了发送路径…

EIGRP 配置,详解拓扑表,路由汇聚

1.3 EIGRP 拓扑,路由以及汇聚 1.3.1 实验目的 通过对 EIGRP 拓扑,路由以及汇聚相关实验的练习,掌握 EIGRP 建立拓扑信息的方式, 度量计算方法,如何调整度量,非等价负载均衡,以及 EIGRP 末节路…

做完自动化测试,但别让不会汇报毁了你...

pytest 是一个成熟的全功能Python测试工具,可以帮助您编写更好的程序。它与 python 自带的 unittest 测试框架类似,但 pytest 使用起来更简洁和高效,并且兼容 unittest 框架。pytest 能够支持简单的单元测试和复杂的功能测试,pyte…

Verilog带参数的`define用法

宏除了可以进行简单的文本替换,还可以像函数和任务一样传递指定多个参数分别对文本进行对应的替换. 示例1: define Disp(pa,pb,pc) \initial \begin \#1200; \$display("%d \n",(papbpc)); \$display(" data_ pa data_ pb data_ pc %d",(…

C#中用程序代码修改了datagridview中的数据,保存时只对光标当前行有保存解决办法

C#中DataGridView绑定了DataTable后,通过代码修改DataGridView中的数据,总有一行(被修改过并被用户选中的行集合中索引为0的行)不能被UpDate回数据库的问题和解决办法 长江黄鹤 2017-06-26 | 300阅读 | 1转藏 转藏全屏朗读分…

真题详解(UML部署图)-软件设计(五十二)

真题详解(地址索引)-软件设计(五十一)https://blog.csdn.net/ke1ying/article/details/130211684 瀑布模式:适应 开发大型项目,且需求明确。 演化模式:适应 对软件需求缺乏准确认知。 螺旋模式&#xff…

【linux】yum “应用商店” 的基本用法

好多工具 yum软件包查看软件包安装软件卸载软件 yum 通俗的讲,这就似我们手机上的应用商店,只不过是在linux下的。 我们可以用yum来下载东西。 软件包 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序。 但是这样…

19 calloc 和 realloc 虚拟内存分配的调试

前言 前面提到了 malloc 虚拟内存分配相关的内容 malloc 虚拟内存分配的调试(1) malloc 虚拟内存分配的调试(2) 这里提 calloc 和 realloc, 这两个函数 虽然没有 malloc 使用频率那么高 但是 还是有很大的知名度的, 本文这里 我们来看一下 calloc 此函数传入两个参数, 第…

Obsidian中如何创作思维导图Mind-map

使用插件 obsidian-mind-map 1.直接在社区下载安装 设置快捷键或者在左侧竖形打开命令面板搜索关键字“mind”, 或者为了便于使用,设置快捷键,在设置-第三方插件中-选择快捷键 然后按下你想设置的快捷键就可以 我这里设置成了CtrlAltM ,M是…

虚拟数字人的3种驱动方式

虚拟数字人是由计算机程序所构建的具有人类特征的虚拟实体,目前的虚拟数字人经过了三代的更迭,划分每一代更迭的标准则是虚拟数字人的驱动方式。 一、虚拟数字人1.0:动画&CG驱动 虚拟数字人1.0就是目前我们所熟知的,比如&am…

LiveCharts2 初步认识

文章目录 1 LiveCharts2 是什么?2 LiveCharts2 可以做什么?3 简单使用LiveCharts2 ,实现动态曲线图 1 LiveCharts2 是什么? GitHub:https://github.com/beto-rodriguez/LiveCharts2 官网: https://lvchar…

C++ STL学习之【反向迭代器】

✨个人主页: 夜 默 🎉所属专栏: C修行之路 🎊每篇一句: 图片来源 A year from now you may wish you had started today. 明年今日,你会希望此时此刻的自己已经开始行动了。 文章目录 🌇前言&a…

分布式锁-Redisson

分布式锁 1、分布式锁1.1 本地锁的局限性1.1.1 测试代码1.1.2 使用ab工具测试(单节点)1.1.3 本地锁问题演示(集群情况) 1.2 分布式锁实现的解决方案1.3 使用Redis实现分布式锁(了解即可)1.3.1 编写代码1.3.2 压测 1.4 使用Redisson解决分布式锁1.4.1 实现代码1.4.1 压测1.4.2 可…
推荐文章