[ES6] Set and Map data structures

Set

WeakSet

Map

WeakMap

WeakRef

Set

Set itself is a constructor used to generate set data structure. Similar to an array, the value is unique without repetition.

const s = new Set();
s.add("a"); // add to
s.add("b");

console.log(s, s.size); // Set { 'a', 'b' } 2

When adding a value to Set, no type conversion occurs, that is, 5 and "5" are different values, which is similar to the strict equality operator (= = =). Different from = = = when adding NaN to Set, it will be considered that NaN is equal to itself. When adding NaN repeatedly, it will be de duplicated; The strict equality operator assumes that NaN is not equal to itself.

Two objects are always unequal.

The Set function can accept an array (or other data structures with iterable interface) as a parameter for initialization.

const set = new Set([1, 2, 3, 4]);
console.log(set); // Set { 1, 2, 3, 4 }

const s = new Set([[1, 2], [3, 4]]);
console.log(s); // Set { [ 1, 2 ], [ 3, 4 ] }

Array de duplication

  • [... new Set(array)] deconstruction

  • Array.from() converts the Set structure to an array

// Array de duplication
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
console.log([...items]); // [1, 2, 3, 4, 5]

// Remove duplicate characters from string
console.log([...new Set("abbbc")].join("")); // "abc" (convert the string into a Set structure, deconstruct it into an array, and convert it into a string)

Set instance properties and methods

Properties:

  • Constructor constructor, which is Set function by default

  • size returns the total number of members of the Set instance

method:

  • add(value) adds a value and returns the Set structure itself. It can be chain written.

  • delete(value) deletes a value and returns true / false, indicating whether the deletion is successful.

  • has(value) looks up the value and returns true / false, indicating whether the value exists.

  • clear() clears all members and returns no value.

ergodic

  • keys() returns the key name traverser object.

  • values() returns the key value traverser object. The default ergodic interface of the Set structure is values().

  • entries() returns the key value pair iterator object.

  • forEach() has no return value.

The traversal order of Set is the insertion order.

Set structure has no key name but only key value (or key name and key value are the same value).

The instance of the Set structure is traversable by default, and its default iterator generation function is its values method. This means that you can omit the values method and directly iterate over the Set with the for...of loop.

let set = new Set(['red', 'green', 'blue']);

for (let x of set) {
  console.log(x);
}
// red
// green
// blue

The map and filter methods of the array can also be used indirectly for Set.

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// Union
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// intersection
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// Difference set of (a) relative to b
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

WeakSet

Similar to Set, it is also a collection of non duplicate values. Different from Set:

  • Members of a WeakSet can only be objects, not values of other types.

  • All objects in the WeakSet are weak references. That is, the garbage collection mechanism does not consider the reference of the WeakSet to the object, that is, if other objects no longer reference the object, the garbage collection mechanism will automatically recover the memory occupied by the object, regardless of the existence of the object in the WeakSet.

  • WeakSet is not traversable. Members are weak references and may disappear at any time. The traversal mechanism cannot guarantee the existence of members. Members may disappear just after traversal.

Usefulness: DOM nodes can be stored. There is no need to worry about memory leakage when these nodes are removed from the document.

// new WeakSet()
const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a); // WeakSet {[1, 2], [3, 4]}
typeof a; // Object 


const b = [1, 2, 3];
const weakSet = new WeakSet(b); // report errors
typeof b; // Object

// new Set()
const c = [2, 3];
const set = new Set(c); // Set { 2, 3 }

Arrays are high-order objects similar to lists. Both new Set(arr) and new WeakSet(arr) are stored by converting array members into members of Set / WeakSet. The second example reports an error because the members of array b are not objects, and the members of WeakSet can only be objects.

Three methods:

  • add(value) adds a member.

  • delete(value) deletes a member. Returns true / false.

  • has(value) indicates whether a value exists and returns true / false.

The WeakSet has no size attribute, and there is no way to traverse its members.

Map

Set of key value pairs. Unlike objects, the range of keys is not limited to strings, and various types of values (including objects) can be used as keys.

As a constructor, Map can also accept an array as a parameter. The array members are arrays representing key value pairs. In fact, any data structure with Iterator interface and each member is a two element array (representing key value) can be used as a parameter of the Map constructor.

The new Map(params) parameter only meets the following requirements: 1. It has an Iterator interface; 2. Its members are in the form of ["key", "value"] (two element array).

const arr = [
  ['title',"This is the title"],
  ['content',"This is the content"]
]
const map = new Map(arr);
console.log(map); // Map {'title' = > 'this is the title', 'content' = > 'this is the content'}

console.log(map.has("title")); // true
console.log(map.get("title")); // This is the title

map.set("author","author XXX");

console.log(map.size); // 3

Only references to the same object are treated as the same key by Map. Two instances of the same value. It is treated as two keys in the Map.

const map = new Map();

// Two instances of the same value
const a1 = ['a'];
const a2 =['a'];
map.set(a1, '1').set(a2, '2');
console.log(map); // Map { [ 'a' ] => '1', [ 'a' ] => '2' }

map.clear();

// Same instance
const b = ['b'];
map.set(b, 'bbbb');
console.log(map); // Map { [ 'b' ] => 'bbbb' }

map.set(b, 'bccc');
console.log(map); // Map { [ 'b' ] => 'bccc' }

The key of Map is actually bound to the memory address. As long as the memory address is different, it is regarded as two keys. If the key of a Map is a value of a simple type (number, string, Boolean), as long as the two values are strictly equal, the Map treats it as a key. For example, 0 and - 0 are the same key, and true and "true" are different keys.

Although NaN is not strictly equal to itself, Map treats it as the same key.

Properties and methods

Properties:

  • size returns the total number of members.

method:

  • set(key,value) sets the key value and returns Map. Chain writing can be used.

  • get(key) gets the value corresponding to the key. If the key cannot be found, return undefined.

  • has(key) indicates whether there is a key and returns true / false.

  • delete(key) deletes the key. Returns true / false.

  • clear() clears all members. No return value.

ergodic

  • keys() returns the traversal of the key name.

  • values() returns the iterator of the key value.

  • entries() returns the traversal of all members. The default traversal interface of Map is entries ().

  • forEach()

The traversal order of the Map is the insertion order.

const arr = [
  ['title',"This is the title"],
  ['content',"This is the content"]
]
const map = new Map(arr);

// Extend the operator to convert the Map structure into an array structure
console.log([...map]); // [['title', 'this is the title'], ['content', 'this is the content']]

// entries()
for(let item of map.entries()) {
  console.log(item); // ['title ',' this is the title '], ['content', 'this is the content']
}

// The above for...of code is equivalent to:
for(let item of map) {
  console.log(item); // ['title ',' this is the title '], ['content', 'this is the content']
}

// forEach()
map.forEach((value, key) => {
  console.log(`${key}-${value}`); // Title - this is the title, content - this is the content
});

Map to object: if all map keys are strings, it can be converted to objects without damage. If there is a non string key name, the key name name name will be converted to a string and used as the key name of the object.

Object to Map:

  • Method 1 (Map constructor): convert each key value pair of the object into an array through Object.entries(), return a two-dimensional array, and then convert it into a Map structure through new Map(arr).

  • Method 2 (set method of Map): obtain the attribute name of the object through Object.keys() as the key of the Map structure, and the attribute value of the object as the value of the Map structure.

const obj = {
  "title":"title",
  "content":"content"
}

console.log(Object.entries(obj)); // [['title ',' title '], ['content', 'content']]

// Object to Map 
// Method 1: Map constructor
const map = new Map(Object.entries(obj));
console.log(map); // Map {'title' = > 'title', 'content' = > 'content'}


// Method 2: add members in the set method of Map
const m = new Map();
for(const k of Object.keys(obj)) {
  m.set(k, obj[k]);
}
console.log(m); // Map {'title' = > 'title', 'content' = > 'content'}

Convert Map to JSON:

  • When the key s are all strings: first convert the Map to an object, and then convert it to an object JSON through JSON.stringify(obj).

  • If the key is not a string, first convert the Map to an array, and then convert it to array JSON through JSON.stringify(arr).

Convert JSON to Map:

  • When the key s are all strings: convert them to objects through JSON.parse(jsonStr), and then convert the objects to maps.

  • key is not a string: convert it to an array through JSON.parse(jsonStr), and then convert the array to a Map.

WeakMap

Similar to Map, it is also a collection used to generate key value pairs. Only objects are accepted as key names.

The features are the same as those of WeakSet.

const wm = new WeakMap();
let key = {};
let obj = {foo: 1};

wm.set(key, obj);
obj = null;
wm.get(key);// Object {foo: 1}

Note that the WeakMap weak reference is only the key name, not the key value. The key value is still a normal reference. Therefore, even if the reference of obj is eliminated outside the WeakMap, the reference inside the WeakMap still exists.

WeakRef

A weak reference for creating objects directly.

let target = {};
let wr = new WeakRef(target); // A new object of opportunity target was created wr

In the above code, wr is an instance of WeakRef, which is a weak reference to target.

The WeakRef instance object has a deref() method that returns the original object if it exists. If the original object has been cleared by the garbage collection mechanism, the method returns undefined.

A great use of weak reference objects is as a cache. When they are not cleared, they can take values from the cache. Once the cache is cleared, it will automatically become invalid.

Once the weak reference of the original object is created by using WeakRef(), the original object will not be cleared in this round of time cycle, but only in the later event cycle.

FinalizationRegistry

Posted by johnSTK on Sat, 06 Nov 2021 00:30:09 -0700