前言
记一次 Map 对象的使用
简介
ES6 提供了 Map 数据结构。它类似对象,是键值对的集合。
-
Map对象保存键值对,并且能够记住键的原始插入顺序。 -
任何值(对象或者原始值)都可以作为一个键或一个值。
-
具有
size属性。
属性
size用于返回 一个 Map 对象的成员数量
const initMap = new Map([
['forever', 'you know you love me'],
['luckdog', 'that is interesting'],
])
// Map 构造函数接受数组作为参数,实际上执行的是👇
const list = [
['name', 'zhangsan'],
['age', 26]
];
const newMap = new Map();
list.forEach(([key, value]) => newMap.set(key, value));
console.log(initMap.size, 'initMap.size'); // 2
console.log(newMap.size, 'newMap.size'); // 2
基本方法
-
new Map()创建一个新的 Map 对象。 -
set()为 Map 对象中添加或更新一个指定了键(key)的值(value)。返回 Map 对象。 -
get()获取 Map 对象中指定键的值。若找不到,返回undefined -
keys()返回一个引用的 Iterator 对象。它包含按照顺序插入 Map 中每个元素的 key 值。 -
values()同 keys(),返回 value 值。 -
entries()返回自身所有成员。
const testMap = new Map();
testMap.set('forever', 'you know you love me');
testMap.set('luckdog', 'that is interesting');
// Map(2) {'forever' => 'you know you love me', 'luckdog' => 'that is interesting'}
console.log(testMap, 'testMap');
testMap.get('forever'); // 'you know you love me'
// MapIterator {'forever', 'luckdog'}
const mapKeys = testMap.keys();
// MapIterator {'you know you love me', 'that is interesting'}
const mapValues = testMap.values();
// 可以通过 扩展运算符 将 Map 结构快速转为数组结构
[...mapKeys]
[...mapValues]
注意: 如果 Map 的键是基本类型(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键。另外undefined和null是两个不同的键。Map 将NaN视为同一个键。
// eg:
const testMap = new Map();
testMap.set(+0, 0);
testMap.get(-0); // 0
testMap.set(true, 1);
testMap.get('true'); // undefined
testMap.set(undefined, 1);
testMap.set(null, 2);
testMap.get(undefined); // 1
testMap.get(null); // 2
testMap.set(NaN, 1);
testMap.get(NaN); // 1
其他方法
-
has()返回布尔值,用来表明 Map 中是否存在指定元素。 -
delete()删除 Map 对象中指定元素,返回true。删除失败则返回false -
clear()移除 Map 对象中所有元素。无返回值。 -
forEach()与数组方法类似,可实现遍历。
const testMap = new Map()
testMap.set('name', 'liming');
testMap.set('age', 24);
testMap.forEach((value, key, map) => {
console.log(value, key, map)
})
testMap.has('name'); // true
testMap.delete('age'); // true
testMap.delete('haha'); // false
testMap.clear(); // undefined
应用
- 写一个 LRU 缓存函数
LRU(Least Recently Used)算法是一种常见的页面置换算法,选择最近最久未使用的页面予以淘汰。
设计原理: 当数据在最近一段时间经常被访问,那么它在以后也会经常被访问。这意味着,如果经常访问的数据,我们需要其能够快速命中,而不常访问的数据,我们会在超出容量限制后,将其淘汰。
/**
* @param {number} capacity 容量限制
*/
var LRUCache = function (capacity) {
this.capacity = capacity; // 存储当前容量限制
this.cache = new Map(); // 初始化 Map 对象,用于缓存
};
/**
* @param {number} key
* @return {number} 存在则返回当前键(key)对应的值,否则返回 -1
*/
LRUCache.prototype.get = function (key) {
// 如果关键字 key 不存在缓存中
if (!this.cache.has(key)) {
console.log(-1)
return -1
}
// 获取关键字的值,删除并重新存储再尾部
const value = this.cache.get(key)
this.cache.delete(key);
this.cache.set(key, value);
console.log(value)
return value
};
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function (key, value) {
if (this.cache.has(key)) {
// 如果当前键(key)存在,则删除并重新存储到 Map 对象尾部
this.cache.delete(key)
} else if (this.cache.size >= this.capacity) {
// 如果是新增操作,则删除 Map 第一个键值对(最早记录),并将新元素存储到 Map 对象尾部
this.cache.delete(this.cache.keys().next().value);
}
this.cache.set(key, value);
};
/**
* LRUCache 对象将被实例化和调用
* const lruCache = new LRUCache(capacity);
* const param_1 = lruCache.get(key);
* lruCache.put(key, value);
*/
const lruCache = new LRUCache(2);
lruCache.put(1, 1);
lruCache.put(2, 2);
lruCache.get(1); // 1
lruCache.put(3, 3);
lruCache.get(2); // -1,表示未找到
lruCache.put(4, 4); // 该操作会使关键字 1 作废
lruCache.get(1); // -1
lruCache.get(3); // 3
lruCache.get(4); // 4
参考
最后
- 文章是自己手敲,是对工作日常的总结,如有错误之处,敬请指正
- 如果遇到什么问题就留言吧,能解决大家帮忙一起解决一下
- 后续有问题的话会一直修改补充