面试管:来,小卡拉米,来个最基本的,说一下Set和Map的理解

image.png

听到这个题之后的内心独白:

卧槽,我都是背的高达上,为啥来个基本的,没准备呀,这让我怎么吹牛逼,我特码的面的可是高级呀,不应该问我:项目调优、首屏优化、打包优化等问题吗?这个面试管不安套路出牌呀,完了,兜不住了,大爷的,嘎了,凉了,gg了,我高大上的八股文白背了,哎,只能江湖在见了!

Set和Map

概念说明

我们想一个问题,ES6中为啥要新增Set和Map这两种数据结构呢?为啥类似于Java中都有Set和Map这两种数据结构,而且还有其变形。

官方回答(八股文答案,就是没毛病,感觉说了跟没说一样,呵呵):

总的来说,ES6中新增的Set和Map数据结构,主要是为了提供更强大和灵活的数据操作能力,以满足更复杂的编程需求。

什么是Set

Set我们可以叫做一种集合得数据结构

什么是Map

Map我们可以叫做一种字典得数据结构

那什么是集合?什么又是字典?

集合:是由一堆无序的、相关联的,而且不能重复的内存结构组成的组合

字典:是一些元素的集合。每个元素有一个称作key 的域,不同元素的key 各不相同

他们的共同点和不同点:

  • 共同点:集合、字典都可以存储不重复的值
  • 不同点:集合是以[值,值]的形式存储元素,字典是以[键,值]的形式存储

使用示例

set 初始化
  • 使用 new Set() 创建一个空 Set
  • 使用 new Set(iterable) 创建一个包含 iterable 中所有值的 Set

着重注意一下第二个new Set(iterable)的这种形式,iterable是指可迭代的。

// 初始化一个set数据结构
const set1 = new Set(); // 创建一个空set
const set2 =  new Set([1,2,3]); // 创建一个包含三个值的set
const set3 = new Set('abc'); // 创建一个包含三个字符的 Set
const set4 = new Set(new Map([['a', 1], ['b', 2]])); // 创建一个包含两个键值对的 Set
Set的用法

只要谈起数据结构,最基本的操作就是增删改查,Set相关常用的API如下:

  • add: 添加某个值(别乱想,添加只有各个方法,可别乱联想数组的push,那你可能数组用多了)
  • delete: 删除某个值
  • has:返回一个布尔值,表明是否含有这个值
  • clear:清空所有的成员

上面增删改查的API没啥好说的。

Set的大小或者说成员的个数是size属性,你可别来个length,length是数组的长度。

数据存在完了,我们要干啥呢?自然就是遍历数据:

Set提供的遍历方法

  • keys: 返回键名的遍历器
  • values: 返回键值的遍历器
  • entries:返回键值对的遍历器
  • forEach:使用回调函数遍历每个成员 (别大惊小怪,用forEach遍历数组,怎么人家Set就不能有)
  • for…of: 迭代Set中所有的成员

稍微发泄一下:

不行,这个得上示例,八股文背诵得多了,有点串了,不上示例,印象不深刻呀,干就完了,大爷的。

特娘的,现在这个吊环境,你不上点花活,面试管都记不住你,关键是我特妈的基本的API都背串了,还上花活,

很是苦逼。我现在用AIGC编程,可惜面试的时候不让我用呀,哈哈。

操,想转行,一看别的行业也是遍地尸体,回头一想,要是转行了那我前期的积累(没啥价值,还不舍得扔的 积累)不就都废了,

妈的,算了,继续跟你们卷,我要一天背10个八股文,卷死你们,哈哈。

遇到点挫折,就特妈的大环境不好,怎么你到哪,那就大环境不好了,哈哈,要想PUA别人就得先PUA自己,我要把我自己PUA死,要不怎么撑下去和你们卷。

他妈的,总之,干就完了。

// 初始化一个set数据结构
const set1 = new Set(); // 创建一个空set
const set2 =  new Set([1,2,3]); // 创建一个包含三个值的set
const set3 = new Set('abc'); // 创建一个包含三个字符的 Set
const set4 = new Set(new Map([['a', 1], ['b', 2]])); // 创建一个包含两个键值对的 Set// 一般来说比较常用的是values, entries,forEach, for...of方法// forEach
set2.forEach(value => { console.log(value) });//  for...of
for (const value of set2) { console.log(value) }// values:  注意返回值是个遍历器,要遍历期中的数据才可以用
const iterator1 = set3.values();
for (const value of iterator1) { console.log(value) }// entries:  返回的也是迭代器,只是迭代器每一项的值是数组[index, value]
const iterator2 = set2.entries();
for (const entry of iterator2) {console.log(entry) }
Map初始化

Map类型是键值对的有序列表,而键和值都可以是任意类型(包括原始值和对象),Map本身是一个构造函数,用来生成Map数据结构(我就问一下子,我八股文背的怎么样,服不服)。

Map的特性:

  • 键值对: Map 中的每个元素都是一个键值对,键可以是任何类型,值可以是任何类型。
  • 无序:Map 中的元素是无序的,插入顺序不会影响迭代顺序。
  • 唯一键:Map 中的键是唯一的,不允许重复。
  • 高效:Map 在查找、插入和删除操作方面都非常高效。

创建Map:

可以使用 new Map() 创建一个空 Map,也可以使用 new Map(iterable) 创建一个包含 iterable 中所有键值对的 Map。

const map1 = new Map(); // 创建一个空 Map
const map2 = new Map([['a', 1], ['b', 2]]); // 创建一个包含两个键值对的 Map// 这个有点意思,注意看,还不抓紧复制到控制台看看,等啥呢,大兄弟
const map3 = new Map(new Set([['a', 1], ['b', 2]])); // 创建一个包含两个键值对的 Map// 哈哈,其实map2和map3创建是一样的,看我花活玩的怎么样。
Map的用法

继续轮我三板斧,来,上增删改查,不行,说增删改查有点low,这把换个洋气点的,CRUD,怎么样?是不是跟国际接轨了。

  • 添加元素:大哥他不可是add哈,add可是人家Set的,它的是set,对的,使用 map.set(key, value) 添加一个键值对到 Map 中
  • 删除元素:使用 map.delete(key) 删除一个键值对从 Map 中。
  • 检查元素是否存在:使用 map.has(key) 检查 Map 中是否包含某个键。
  • 获取元素:使用 map.get(key) 获取某个键对应的值。大哥,map有这个get方法,Set可没有哈,记清楚了

map的长度跟Set一样,也是size属性,表示元素集合的个数。

数据存储完了,是不是要上遍历了,搞起来:

  • 使用 forEach 迭代 Map 中的所有键值对
  • 使用 for...of 迭代 Map 中的所有键值对
  • 使用 keys 方法获取 Map 中所有键的迭代器
  • 使用 values 方法获取 Map 中所有值的迭代器
  • 使用 entries 方法获取 Map 中所有键值对的迭代器
const map1 = new Map(); // 创建一个空 Map
const map2 = new Map([['a', 1], ['b', 2]]); // 创建一个包含两个键值对的 Map
const map3 = new Map(new Set([['a', 1], ['b', 2]])); // 创建一个包含两个键值对的 Map// forEach,遍历键值对哈!三遍:键值对
map1.forEach((value, key) => { console.log(key, value)} );// 同上
for (const [key, value] of map2) {console.log(key, value)}// 所有的键
const keys = map3.keys();
for (const key of keys) {console.log(key) }// 所有的值
const values = map3.values();
for (const value of values) { console.log(value) }// 键值对
const entries = map3.entries();
for (const [key, value] of entries) { console.log(key, value) }

不行拿到控制台多输几遍,没啥丢人的,不满你说,我打了七八遍,哈哈,是不是很有天赋,仅仅七八遍就记住了一半,小卡拉米们,你们已经输在起跑线了,输在天赋上了,哈哈!

Set常见用法

去重

Set数据结构中不允许重复的元素,利用这个特性可以很简洁的实现数组去重

[...new Set([1,2,3,3,1,2])]

不考虑性能的情况下,Set去重可以做到相当的简洁。

交集

可以使用Set计算两个数组的交集,写法也是相当的简洁。

const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);// 交集
const intersection = new Set([...set1].filter(x => set2.has(x)));
并集
const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);// 并集
const union = new Set([...set1, ...set2]);
差集
const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);// 差集
const difference = new Set([...set1].filter(x => !set2.has(x)));
相等

判断两个set是否相等

const set1 = new Set([1, 2, 3]);
const set2 = new Set([1, 2, 3]);// 方法一:比较两个 Set 的大小和元素
console.log(set1.size === set2.size && [...set1].every(x => set2.has(x))); // true// 方法二:使用 Set 的 `equals` 方法
console.log(set1.equals(set2)); // true

来放松一下:

在惊叹Set和Map中,喊着一声声牛逼,在牛逼中逐渐的迷失自己,感觉自己又可以了,哈哈,这是错觉,小卡拉米,干就完了!冲吧,小卡拉米!

哈拉西大,娘希匹,特奶奶的上Map!

Map常见用法

转换

怎么说呢,其实Map的转换是很常见的用法,一定要掌握的。

  • Map 转为数组:使用 [...map]Array.from(map) 将 Map 转换为数组。
  • 数组转为 Map:使用 new Map(iterable) 将数组转换为 Map。
  • Map 转为对象:使用 Object.fromEntries(map) 将 Map 转换为对象。
  • 对象转为 Map:使用 new Map(Object.entries(obj)) 将对象转换为 Map。
// map转换为数组
const arr = [...map1]; // [["a", 1]]
// 数组转换map
const map4 = new Map([['a', 1], ['b', 2]]);
// Map转换对象(这个有点意思哈,记住了,有用的)
const obj = Object.fromEntries(map4); // {a: 1, b: 2}
// 对象转换map
const map5 = new Map(Object.entries(obj)); // Map {a => 1, b => 2}
模拟字典

可以使用 Map 来模拟字典,键可以是单词,值可以是单词的定义。

const dictionary = new Map([["apple", "一种水果"],["banana", "一种水果"],["cat", "一种动物"],
]);console.log(dictionary.get("apple")); // "一种水果"
缓存数据

这个有点意思,可以使用 Map 来缓存数据,提高性能。

const cache = new Map();function getData(key) {if (cache.has(key)) {return cache.get(key);} else {const data = fetch(key);cache.set(key, data);return data;}
}const data = getData("https://www.example.com");
对象去重

可以使用 Map 来对对象进行去重,例如只保留对象的 id 属性

const objects = [{ id: 1, name: "John" },{ id: 2, name: "Mary" },{ id: 1, name: "Alice" },
];const uniqueObjects = new Map();for (const object of objects) {if (!uniqueObjects.has(object.id)) {uniqueObjects.set(object.id, object);}
}console.log(uniqueObjects.values()); // [ { id: 1, name: "John" }, { id: 2, name: "Mary" } ]
统计元素次数

可以使用 Map 来统计元素出现的次数。

const words = ["a", "b", "c", "a", "b"];
const wordCounts = new Map();for (const word of words) {if (wordCounts.has(word)) {wordCounts.set(word, wordCounts.get(word) + 1);} else {wordCounts.set(word, 1);}
}// 上面的写法可以玩花活的,你懂的,娘希匹,反正我就觉得这种写法最好,可读性好高。(翻译成人话就是:我太菜了,这个才刚看明白,还花活,绕了我吧)console.log(wordCounts); // Map { "a" => 2, "b" => 2, "c" => 1 }
实现 LRU 缓存

可以使用 Map 来实现 LRU 缓存,即最近最少使用缓存。

我擦,都别拦我,我感觉我又行了,我可以去搞算法了,啥动态规划、回溯、贪心等等,都不在话下,就是主打一个看不懂,

等我去召唤法师,卷死你们,哈哈。

class LRUCache {constructor(capacity) {this.capacity = capacity;this.cache = new Map();}get(key) {if (this.cache.has(key)) {const value = this.cache.get(key);this.cache.delete(key);this.cache.set(key, value);return value;} else {return undefined;}}set(key, value) {if (this.cache.size === this.capacity) {const oldestKey = this.cache.keys().next().value;this.cache.delete(oldestKey);}this.cache.set(key, value);}
}const cache = new LRUCache(2);cache.set("a", 1);
cache.set("b", 2);console.log(cache.get("a")); // 1
cache.set("c", 3);console.log(cache.get("b")); // undefined

扩展

来吧,都说了Set,那不得介绍一下WeakSet,要不怎么显得我花活多(人话是:哎,真他妈的学够了,他们天天更新,我特码的天天跟个菜鸟一样,学学学,时候是个头呀,毁灭吧!)

WeakSet 简介

WeakSet 是 JavaScript 中一种新的数据结构,它用来存储弱引用的集合。与传统的 Set 数据结构不同,WeakSet 中的对象不会阻止垃圾回收机制回收它们。

特性:

  • 弱引用:WeakSet 中的对象是弱引用,这意味着垃圾回收机制可以回收它们,即使它们仍然被 WeakSet 引用。
  • 无序:WeakSet 中的元素是无序的,插入顺序不会影响迭代顺序。
  • 唯一键:WeakSet 中的键是唯一的,不允许重复。
  • 高效:WeakSet 在查找、插入和删除操作方面都非常高效。

WeakMap简介

但用于存储键值对。WeakMap 中的键是弱引用,这意味着垃圾回收机制可以回收它们,即使它们仍然被 WeakMap 引用。

特性:

  • 弱键:WeakMap 中的键是弱引用,这意味着垃圾回收机制可以回收它们,即使它们仍然被 WeakMap 引用。
  • 无序:WeakMap 中的元素是无序的,插入顺序不会影响迭代顺序。
  • 唯一键:WeakMap 中的键是唯一的,不允许重复。
  • 高效:WeakMap 在查找、插入和删除操作方面都非常高效。

等我后续补充WeakSet 和 WeakMap ,我这小卡拉米和你们后边继续交流学习…

总结

基础不过关,都是几把扯淡,牛逼吹的越狠,可能越兜不住。

面试管:下一个问题(小卡拉米,说这么多有用吗,我们只要个性价比高的,能做的了项目即可,你跟我扯这么多,扯这么多高达上的,干啥?一句没说到点子上,净浪费时间,我大外包需要你会这么多,小样)。

面试管内心独白:这个小卡拉米还想隔着跟我装逼,坚决不能惯他,等我搜个高级面试打发来,看我不问死他,娘希匹!

中间内心独白和旁白纯属编造,你的懂得。

哈喽,brother,欢迎来到《新世界》,我可是电梯战神,不给我点赞加收藏,我拿刀嘎你!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【教程】 iOS构建版本无效问题解决方案

引言 在进行iOS应用上架时,有时会遇到构建版本无效的问题,即通过XCode上传成功后,但在App Store Connect的TestFlight中无法显示构建版本,或者显示一会儿后就消失了。本文将介绍可能的原因分析,并提供解决问题的方法。…

webpack基础配置及使用

webpack是什么 是一个现代 JavaScript 应用程序的静态模块打包器。当webpack 处理应用程序时,它会递归地构建一个依赖关系图 ,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle 。主要有 五个核心概念&#xff1a…

电源技术中的TPHR8504PL,LQ(M1W 40V高速同步N沟道150A 功率MOSFET用于高效DC-DC转换器

TPHR8504PL,LQ(M1W是一种MOSFET(金属氧化物半导体场效应晶体管),它是40 Volt N-沟道MOSFET,由N型沟道和P型衬底构成,而P-沟道MOSFET则由P型沟道和N型衬底构成。 TPHR8504PL,LQ(M1W N-沟道MOSFE…

2024 ssh连接linux ,包括连接被拒的解决方案

这里以windows系统 连接 linux(centOS)为例: 一、如果windows 连接时出现: Permission denied, please try again. 连接被拒绝,做出以下修改: 打开linux - Terminal 输入:cat /etc/ssh/sshd_c…

【算法 高级数据结构】树状数组:一种高效的数据结构(一)

🚀个人主页:为梦而生~ 关注我一起学习吧! 💡专栏:算法题、 基础算法~赶紧来学算法吧 💡往期推荐: 【算法基础 & 数学】快速幂求逆元(逆元、扩展欧几里得定理、小费马定理&#x…

Python与FPGA——图像锐化

文章目录 前言一、图像锐化二、Python robert锐化三、Python sobel锐化四、Python laplacian锐化五、FPGA sobel锐化总结 前言 在增强图像之前一般会先对图像进行平滑处理以减少或消除噪声,图像的能量主要集中在低频部分,而噪声和图像边缘信息的能量主要…

品牌要把控质量也要管控价格

在品牌发展的道路上,产品质量的把控非常重要,关系到品牌的竞争力,但品牌要长期发展,产品要获得市场足够份额,还需要有稳定的价格体系做支撑,这个价格不是仅凭品牌单方面的定价而定,而是整个渠道…

Oracle定时任务和存储过程

--1.声明定时任务 DECLAREjob NUMBER; BIGIN dbms_job.sumit(job, --任务ID,系统定义的test_prcedure(19),--调用存储过程?to_date(20240305 02:00,yyyymmdd hh24:mi) --任务开始时间sysdate1/(24*60) --任务执行周期 [每分钟执行…

商业前端TS开发自动化工具

本期作者 一、背景 商业侧的业务比较复杂,B端项目中含有大量常量类的类型判断,且因历史原因,很多常量值前端无法直接知其含义,这既不利于新人的上手,也不利于项目的维护。 在开发协作上,前后端的API沟通&a…

什么是工业边缘网关?工业边缘网关有什么作用?

在数字化和智能化的浪潮下,工业领域正迎来前所未有的变革。其中,工业边缘网关作为这场变革中的重要角色,正逐渐受到人们的关注。那么,什么是工业边缘网关?它如何在工业数字化中发挥作用?今天,就…

Wireshark——获取捕获流量的前N个数据包

1、问题 使用Wireshark捕获了大量的消息,但是只想要前面一部分。 2、方法 使用Wireshark捕获了近18w条消息,但只需要前5w条。 选择文件,导出特定分组。 输入需要保存的消息范围。如:1-50000。 保存即可。

环链表寻找交点

目录 1.题目描述和出处 2.分析 3.代码 1.题目描述和出处 LCR 022. 环形链表 II - 力扣(LeetCode) 描述很简单,寻找交点,找到则返回交点,找不到返回空。 2.分析 如图:(b表示环的长度&#…

springboot3.x集成nacos踩坑,并实现多环境配置

一、nacos安装部署 springboot3.x集成Nacos首先需要将Nacos从1.x升级到2.x,建议直接安装2.x版本,手动将1.x的配置信息迁移到2.x中,先并行一段时间,待全部迁移完成稳定运行之后再停掉1.x,升级和安装、操作请查看官方文…

DailyNotes个人笔记管理工具

DailyNotes 是记录笔记和跟踪任务的应用程序,使用markdown进行编辑 部署 下载镜像 docker pull m0ngr31/dailynotes创建目录并授权 mkdir -p /data/dailynotes/config_dir chmod -R 777 /data/dailynotes启动容器 docker run -d --restart always --name mynot…

Java中的数据压缩和存储技术:Zip、GZip与Brotli

第1章:引言 大家好,我是小黑,作为一名Java程序员,在业务开发中,常常面临着一个问题:如何高效地处理和传输这些庞大的数据呢?答案就在于数据压缩技术。数据压缩,简而言之&#xff0c…

SpringBoot+Ajax+redis实现隐藏重要接口地址

🏡浩泽学编程:个人主页 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》 《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 文章目录 …

九型人格测试,8号领袖型人格的职业分析

8号人格,也叫领袖型人格,在九型人格中间,是一种天生领导的存在。他们生性开朗,能够和其他人建立良好的关系,为人不拘小节,遇强则强,坚守心中的理想和正义。不喜欢被人控制,喜欢自己当…

Java并发-并发模型

可以使用不同的并发模型来实现并发系统。一并发模型指定的系统协作线程如何完成他们给予的任务。不同的并发模型以不同的方式拆分任务,线程可以以不同的方式进行通信和协作。本并发模型教程将更深入地介绍撰写本文时(2015年至2019年)使用的最…

大模型时代,华为与中软国际携手“打通AI落地应用最后一公里”

文 | 智能相对论 作者 | 叶远风 大模型驱动千行百业智能化变革已经成为广泛共识,下一步的问题是,企业要如何更好地推进? 近日,“2024中关村论坛系列活动——第二届北京人工智能产业创新发展大会”在北京国家会议中心成功举办&a…

yudao-cloud 学习笔记

前端代码 浏览器打开 https://cloud.iocoder.cn/intro/ F12 执行代码 var aaa $(".sidebar-group-items").find("a"); var ll[]; var tt[]; for(var i0;i<aaa.length;i ){ ll.push("https://doc.iocoder.cn" $(aaa[i]).attr("href&quo…