3.1.1 ES6 Map and Set
Category ES6 Tutorial
Map Object
The Map object holds key-value pairs. Any value (both objects and primitive values) may be used as either a key or a value.
Differences Between Maps and Objects
An Object's keys can only be strings or Symbols, but a Map's keys can be any value.
Keys in a Map are ordered (FIFO principle), whereas keys added to an object are not.
The number of key-value pairs in a Map can be obtained from the size property, while the number of key-value pairs in an Object must be manually calculated.
Objects have their own prototypes, and keys from the prototype chain may conflict with keys you set on the object.
Keys in a Map
Key is a String
var myMap = new Map();
var keyString = "a string";
myMap.set(keyString, "value associated with 'a string'");
myMap.get(keyString); // "value associated with 'a string'"
myMap.get("a string"); // "value associated with 'a string'"
// because keyString === 'a string'
Key is an Object
var myMap = new Map();
var keyObj = {};
myMap.set(keyObj, "value associated with keyObj");
myMap.get(keyObj); // "value associated with keyObj"
myMap.get({}); // undefined, because keyObj !== {}
Key is a Function
var myMap = new Map();
var keyFunc = function () {}; // function
myMap.set(keyFunc, "value associated with keyFunc");
myMap.get(keyFunc); // "value associated with keyFunc"
myMap.get(function() {}) // undefined, because keyFunc !== function () {}
Key is NaN
var myMap = new Map();
myMap.set(NaN, "not a number");
myMap.get(NaN); // "not a number"
var otherNaN = Number("foo");
myMap.get(otherNaN); // "not a number"
Although NaN is not equal to any value, even itself (NaN !== NaN returns true), NaN as a key in a Map is considered the same.
Iterating over a Map
To iterate over a Map, the following two methods are the most advanced.
for...of
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
// Will display two logs. One is "0 = zero" and the other is "1 = one"
for (var [key, value] of myMap) {
console.log(key + " = " + value);
}
for (var [key, value] of myMap.entries()) {
console.log(key + " = " + value);
}
/* This entries method returns a new Iterator object that contains the [key, value] pairs for each element in the Map object in insertion order. */
// Will display two logs. One is "0" and the other is "1"
for (var key of myMap.keys()) {
console.log(key);
}
/* This keys method returns a new Iterator object that contains the keys for each element in the Map object in insertion order. */
// Will display two logs. One is "zero" and the other is "one"
for (var value of myMap.values()) {
console.log(value);
}
/* This values method returns a new Iterator object that contains the values for each element in the Map object in insertion order. */
forEach()
var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
// Will display two logs. One is "0 = zero" and the other is "1 = one"
myMap.forEach(function(value, key) {
console.log(key + " = " + value);
}, myMap)
Operations on Map Objects
Map to Array Conversion
var kvArray = [["key1", "value1"], ["key2", "value2"]];
// The Map constructor can convert a 2D key-value pair array into a Map object
var myMap = new Map(kvArray);
// Using the Array.from function, a Map object can be converted into a 2D key-value pair array
var outArray = Array.from(myMap);
Cloning a Map
var myMap1 = new Map([["key1", "value1"], ["key2", "value2"]]);
var myMap2 = new Map(myMap1);
console.log(original === clone);
// Prints false. The Map object constructor generates a new instance, iterating to create a new object.
Merging Maps
var first = new Map([[1, 'one'], [2, 'two'], [3, 'three']]);
var second = new Map([[1, 'uno'], [2, 'dos']]);
// When merging two Map objects, if there are duplicate keys, the latter will overwrite the former, resulting in values 'uno', 'dos', 'three'
var merged = new Map([...first, ...second]);
Set Object
The Set object lets you store unique values of any type, whether primitive values or object references.
Special Values in a Set
The values stored in a Set are always unique, so it's necessary to determine if two values are identical. There are a few special values that need special treatment:
+0 and -0 are considered identical when stored and compared for uniqueness, so they do not duplicate;
undefined and undefined are identical, so they do not duplicate;
NaN and NaN are not identical, but in a Set, only one NaN can be stored, so they do not duplicate.
Code
let mySet = new Set();
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set(2) {1, 5} This demonstrates the uniqueness of values
mySet.add("some text");
// Set(3) {1, 5, "some text"} This demonstrates the diversity of types
var o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2});
// Set(5) {1, 5, "some text", {…}, {…}}
// This demonstrates that objects with different references are not identical, even if their values are the same, and can be stored in a Set
Type Conversion
Array
// Array to Set
var mySet = new Set(["value1", "value2", "value3"]);
// Using the ... operator, convert Set to Array
var myArray = [...mySet];
String
// String to Set
var mySet = new Set('hello'); // Set(4) {"h", "e", "l", "o"}
// Note: The toString method cannot convert a Set to a String
Uses of Set Objects
Array Deduplication
var mySet = new Set([1, 2, 3, 4, 4]);
[...mySet]; // [1, 2, 3, 4]
Union
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var union = new Set([...a, ...b]); // {1, 2, 3, 4}
Intersection
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}
Difference
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var difference = new Set([...a].filter(x => !b.has(x))); // {1}
#
-
** mokit
* zbi**[email protected]
Difference Calculation:
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var difference = new Set([...[...a].filter(x => !b.has(x)), ...[...b].filter(x => !a.has(x))]); // {1, 4}
1 is the difference between a and b.
4 is the difference between b and a.
** mokit
* zbi**[email protected]
-
** Ice Cube
* 134**[email protected]
Understanding this piece of code can be challenging.
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var intersect = new Set([...a].filter(x => b.has(x))); // {2, 3}
This code requires understanding several concepts.
1、[...a]
[...a] converts a set to an array. This method is commonly used to convert a set to an array.
2、[...a].filter()
Array.filter(function(x)) applies the function function(x) to each element, where x is the value of the element, and decides whether to keep or discard the element based on whether the return value is true or false.
This means iterating over the current array and removing elements for which the function returns false.
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
3、 => is a shorthand method.
x => x * x
is equivalent to:
function(x){return x*x}
So x => b.has(x)
is essentially a function equivalent to function(x){return b.has(x)}
.
4、b.has(x)
Set.has(x) is a method of the set. It checks if the current set contains x, returning true if it does and false if it does not.
So this code can also be written as:
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
var arr = [...a]; // Convert a to an array
var fArr = arr.filter(function(x){ // Use filter to filter the array and return the new array to fArr
return b.has(x); // Check if b contains elements from a, return false if not
});
var intersect = new Set(fArr); // Convert fArr to a set
console.log(fArr);