Map and Set
JavaScript Map and Set (JavaScript 地图 和 集 )
While working with JavaScript, developers waste a lot of time on choosing the right data structure. (当 使用 JavaScript 时, 开发人员 浪费 a lot of time on choosing the right data structure. )
Objects and Arrays are the primary data structures used to store collections of data. Objects are used for storing key/value pairs, and arrays- for indexed lists. To make developers’ life easier, ECMAScript 2015 represented two new kinds of iterable objects: Maps and Sets.
Maps
Maps (地图 )
A map is a key-value pairs collection that can apply any data type as a key, maintaining the sequence of its entries. (A map is a key-value pairs collection that can apply 任何 data type as a key, 保持 其 条目的 序列 。)
Maps contain both elements of objects and array. But, conceptually, they are similar to objects. (地图 包含 对象 和 数组的 元素 。 但是, 从概念上讲, 它们 与 物体相似 。)
The primary distinction is that maps allow any type of keys. ( 主要 的区别 是 地图 允许 任何 类型 键的 。)
The main properties and methods of maps are the following:
new Map() – creating the map. (- new Map () – creating the map. )
map.set(key, value) – storing the value by the key. (- map.set (key, value) – storing the value by the key. )
map.get(key) – returning the value by the key, undefined if no key exists in the map. (- map.get (key) – 通过 key返回 值 , undefined if no key exists in the map. )
map.has(key) – returning true if there exists a key, and false otherwise. (- map.has (key) – 返回 true if there exists a key , and false else. )
map.delete(key) – removing the value by the key. (- map.delete (key) – 通过 键删除 值 。)
map.clear() – removing everything from the map. (- map.clear () – 从 地图中删除 所有内容 。)
map.size – returning the current element count. (- map.size – 返回 当前 元素 计数。)
So, you can use new Map() to create a map like this:
let map = new Map();
map.set('10', 'str'); // string key
map.set(10, 'num'); // numeric key
map.set(false, 'bool'); // boolean key
//Map can save the type, and a regular object can convert keys to a string,
//so these two values are different:
console.log(map.get(10)); // 'num'
console.log(map.get('10')); // 'str'
console.log(map.size); // 3
From this example, you can notice that they are not converted to strings, as any type of key is allowed. (从 这个 示例中, 您 可以 通知 他们 没有 转换为 字符串, 作为 任何 类型 的 密钥 是允许的 。)
Also, maps are capable of using objects as keys as demonstrated below:
let js = {
name: "Javascript"
};
// for each book, let's save the number of visits
let visitsCountMap = new Map();
// js is the key for the map
visitsCountMap.set(js, 250);
console.log(visitsCountMap.get(js)); // 250
One of the most significant map features is using objects as keys:
let js = {
name: "Javascript"
};
let visitsCountObj = {}; // try to use an object
visitsCountObj[js] = 250; // try to use js object as the key
console.log(visitsCountObj["[object Object]"]); // 250
In the example above, visitsCountObj is an object that converts all the keys like js to strings. So, the string key is “[object Object]“. But, it is not completely right. (在上面的 示例 中, visitsCountObj 是一个 对象 , 将 所有 转换为 字符串。 因此, string key 是 “[object Object]” 。 但是, 它 并不完全正确 。 )
The SameValueZer algorithm is used for testing keys for equivalence. It is similar to ===. The only difference is that NaN is equal to NaN and can be applied as the key. You can’t change or customize this algorithm. ( SameValueZer 算法 用于 测试 密钥 等效性。 It is 相似 到 = = 。 仅 差异 是 NaN 等于 NaN 和 can be applied as the key. 您 不能 更改 或 自定义 此 算法。)
There is another option, too: the calls can be chained, as each map.set call returns the map, like this:
map.set('10', 'str')
.set(10, 'num')
(.set (10, 'num'))
.set(false, 'bool');
Iterating over Map
Iterating over Map (在 地图 上迭代 )
Three main methods exist that allow looping over a map. They are as follows:
map.keys() – returning an iterable for keys, (- map.keys () – return an iterable for keys, )
map.values() – returning an iterable for values, (- map.values () – return an iterable for values, )
map.entries() – returning an iterable for entries [key, value], it’s applied by default in for..of. (- map.entries () – return an iterable for entries [key, value] , it ’s applied by default in for.. of . )
An example is as follows:
let priceMap = new Map([
['banana', 250],
['apple', 150],
['peach', 200]
]);
// iterate over keys (fruit)
for (let fruit of priceMap.keys()) {
console.log(fruit); // banana, apple, peach
}
// iterate over values (amounts)
for (let amount of priceMap.values()) {
console.log(amount); // 250, 150, 200
}
// iterate over [key, value] entries
for (let entry of priceMap) { // the same as of priceMap.entries()
console.log(entry); // banana, 250 (and so on)
}
Also, there exists a built-in forEach method, equivalent to Array:
let priceMap = new Map([
['banana', 250],
['apple', 150],
['peach', 200]
]);
// running the function for each pair (key, value)
priceMap.forEach((value, key, map) => {
console.log(`${key}: ${value}`); // banana, 250 etc
});
Using Object.entries
Using Object.entries (使用 Object.entries )
Once a map is generated, an array can be passed with key/value pairs as follows:
// array of pairs [key, value]
let map = new Map([
['10', 'str'],
[10, 'num'],
[false, 'bool']
]);
console.log(map.get('10')); // str
A map can be created from an object as follows:
let obj = {
name: "Maria",
age: 20
};
let map = new Map(Object.entries(obj));
console.log(map.get('name')); // Maria
Object.fromEntries
Object.fromEntries (Object.fromEntries )
After learning how to create a map from a plain object using (在 学习 如何 创建 a 地图 from a plain object using ) Object.entries(obj), let’s get to the opposite. (Object.entries (obj) , Let ’s get to the opposite. )
The Object.fromEntriesmethod allows performing the reverse process. Once you have an array of [key, value] pairs, it will generate a object from them like this:
let counts = Object.fromEntries([
['banana', 4],
['apple', 2],
(苹果 2)
['peach', 3]
]);
// now counts = { banana: 4, apple: 2, peach: 3 }
console.log(counts.apple); // 2
So, Object.fromEntries can be used for getting a plain object from the map. Once you store data inside a map, you should pass it to a third-party code, expecting a plain object, as demonstrated below:
let map = new Map();
map.set('banana', 4);
map.set('apple', 2);
map.set('peach', 3);
let obj = Object.fromEntries(map.entries()); //(*)
// obj = { banana: 4, apple: 2, peach: 3 }
console.log(obj.apple); // 2
The (*) line can be made shorter:
let obj = Object.fromEntries(map); // .entries()
Sets
Sets (套装 )
A set is a specific collection of “set of values” where every value can take place only once. (A set 是 “set of values” 的 特定 集合,其中 每个 value 可以 取 地方 仅 一次。)
The primary methods used by set are shown below:
new Set(iterable) – creating the set, and if an iterable object is supplied (usually an array), copying values from it to the set. (- new Set (iterable) – creating the set, and if an it and if an it and an object is provided (通常是 an array ), copying values from it to the set. )
set.add(value) – adding a value, returning the set itself. (- set.add (value) – add a value, return the set itself. )
set.delete(value) – removing the value, returning true if the value is there at the moment of the calling, otherwise false. (- set.delete (value) – 删除 值, 返回 true 如果 值 是 有 在 调用的 时刻 , 否则 false 。)
set.has(value) – returning true if the value is there inside the set, otherwise false. (- set.has (value) – 返回 true 如果 值 在 集合内 , 否则 false 。)
set.clear() – removing all from the set. (- set.clear () – 从 集合中删除 所有 。)
set.size – counting the elements. (- set.size – 计算 元素。)
Set can be useful in various situations. For example, visitors are coming to your site, and you wish to remember all of them. Take into account that repeated visits must not lead to duplicates, and each visitor should be counted once. It can be easily done with Set like this:
let set = new Set();
let js = {
name: "Javascript"
};
let html = {
name: "Html"
};
let css = {
name: "Css"
};
// visits, some books come multiple times
set.add(js);
set.add(css);
set.add(html);
set.add(js);
set.add(css);
// set only stores unique values
console.log(set.size); // 3
for (let user of set) {
console.log(user.name); // Javascripr (then Css and Html)
}
Iterating over Set
Iterating over Set ( Iterating over Set )
Looping over a set is possible either with for..of or with for..of like this:
let set = new Set(["bananas", "apples", "peaches"]);
for (let value of set) {
console.log(value);
}
set.forEach((value, valueAgain, set) => {
console.log(value);
});
Here is an interesting and a bit funny fact. The callback function that is passed inside forEach includes three arguments: a value, the same value valueAgain, and the target object. As you can see, the same value can appear in the arguments twice.
That can seem strange but helps in replacing the Map with Set in particular cases. ( CAN 看起来 奇怪 ,但 帮助 在 特定 个案中将 地图 替换为 集 。 )
Summary
Summary (摘要 )
In this chapter, we represented to you Map and Set. Now, let’s summarize what was covered in general. While Map is a collection of keyed values, Set represents a collection of unique values. Each of them has its methods and properties. (在本章中, 我们 表示 到 您 地图 和 集合。 现在, 让我们总结一下 在 一般中涵盖的内容 。 地图 是 键入 值的 集合, 集合 代表 唯一 值的 集合 。 他们 的每个 都有 其 方法 和 属性。)
Both of these data structures add extra capabilities of JavaScript and can simplify common tasks (for example, detecting the length of a key/value pair collection or deleting duplicate items from a data set). ( 这些 数据 结构 添加 JavaScript 和 can 的额外 功能 简化 常见 任务 (例如, 检测 a 键/值 对的 长度 集合 或 从 a data 集删除 重复 项目 )。)