Map
- 概念
- Map 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)
- 操作方法
- new Map() —— 创建 map。
- map.set(key, value) —— 根据键存储值。
- map.get(key) —— 根据键来返回值,如果 map 中不存在对应的 key,则返回 undefined。
- map.has(key) —— 如果 key 存在则返回 true,否则返回 false。
- map.delete(key) —— 删除指定键的值。
- map.clear() —— 清空 map。
- map.size —— 返回当前元素个数。
- 迭代
- map.keys() —— 遍历并返回一个包含所有键的可迭代对象,
- map.values() —— 遍历并返回一个包含所有值的可迭代对象,
- map.entries() —— 遍历并返回一个包含所有实体 [key, value] 的可迭代对象,for…of 在- 默认情况下使用的就是这个。
- 拓展
-
使用对象作为键是 Map 最值得注意和重要的功能之一。在 Object 中,我们则无法使用对象作为键。在 Object 中使用字符串作为键是可以的
-
Map 使用 SameValueZero 算法来比较键是否相等。它和严格等于 === 差不多,但区别是 NaN 被看成是等于 NaN。所以 NaN 也可以被用作键。
Set
- 概念
- Set 是一个特殊的类型集合 —— “值的集合”(没有键),它的每一个值只能出现一次。
- 操作方法
- new Set(iterable) —— 创建一个 set,如果提供了一个 iterable 对象(通常是数组),将会从数组里面复制值到 set 中。
- set.add(value) —— 添加一个值,返回 set 本身
- set.delete(value) —— 删除值,如果 value 在这个方法调用的时候存在则返回 true ,否则返回 false。
- set.has(value) —— 如果 value 在 set 中,返回 true,否则返回 false。
- set.clear() —— 清空 set。
- set.size —— 返回元素个数。
- 特点
- 重复使用同一个值调用 set.add(value) 并不会发生什么改变。这就是 Set 里面的每一个值只出现一次的原因。
- 迭代方法
- forEach / for…of
- set.keys() —— 遍历并返回一个包含所有值的可迭代对象,
- set.values() —— 与 set.keys() 作用相同,这是为了兼容 Map,
- set.entries() —— 遍历并返回一个包含所有的实体 [value, value] 的可迭代对象,它的存在也是为了兼容 Map。
WeakMap
- 特点
- WeakMap 和 Map 的第一个不同点就是,WeakMap 的键必须是对象,不能是原始值
- 操作方法
- weakMap.get(key)
- weakMap.set(key, value)
- weakMap.delete(key)
- weakMap.has(key)
- 应用场景
- 额外的数据:
假如我们正在处理一个“属于”另一个代码的一个对象,也可能是第三方库,并想存储一些与之相关的数据,那么这些数据就应该与这个对象共存亡 —— 这时候 WeakMap 正是我们所需要的利器 - 缓存:
另外一个常见的例子是缓存。我们可以存储(“缓存”)函数的结果,以便将来对同一个对象的调用可以重用这个结果
Leetcode 242 有效的字母异位词
视频讲解链接: 学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词
思路
- 创建两个map, 分别存进去字母和出现的字数
- 遍历其中一个 map 的 key / value
- 如果另一个 map 对应的 key / value 一样返回 true 否则 false
代码
var isAnagram = function(s, t) {
if(s.length !== t.length) return false
let mapS = new Map()
let mapT = new Map()
for(let char of s){
mapS.set(char, (mapS.get(char) || 0) + 1)
}
for(let char of t){
mapT.set(char, (mapT.get(char) || 0) + 1)
}
for(let [key, value] of mapS){
if(mapT.get(key) !== value){
return false
}
}
return true
};
Leetcode 349 两个数组的交集
视频讲解链接: 学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集
思路
- 创建两个 set,会把重复的数字去掉
- 遍历其中一个 set, 并查看另外一个 set 是否存在, 存在则存入新数组
代码
var intersection = function(nums1, nums2) {
let setA = new Set(nums1)
let setB = new Set(nums2)
let res = []
setA.forEach(n => {
if(setB.has(n)){
res.push(n)
}
})
return res
};
单行版本
var intersection = function(nums1, nums2) {
return [...new Set(nums1)].filter(n => nums2.includes(n))
};
Leetcode 202 快乐数
思路
- 创建一个 map 存储每轮求出来的结果
- 如果新的结果 map 已经有相同的值返回 false
- 如果等于 1 返回 true
代码
var isHappy = function(n) {
let map = new Map()
let loop = n
while(true){
let arr = String(loop).split('')
loop = arr.reduce((res, item) => {
let cal = +item * +item
return res += cal
}, 0)
if(loop === 1) return true
if(map.has(loop)) return false
map.set(loop, 1)
}
};
Leetcode 1 两数之和
视频讲解链接: 梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!
思路
- 创建一个 map 并遍历数组
- 先求出 target - nums[i] 的值是否在 map 中出现过, 如果出现则返回两个数对应的下标
- 在每轮遍历结束前把当前的数字存入map
代码
var twoSum = function(nums, target) {
let map = new Map()
for(let i = 0; i < nums.length; i++){
let tar = target - nums[i]
if(map.has(tar)){
return [map.get(tar),i]
}
map.set(nums[i], i)
}
};