ES6 Sets and Maps

Set

basic usage

A set is similar to an array, but the members are unique. Set itself is a constructor used to generate the Set data structure.

const a = new Set();
[1,2,3,3,4,1,2,3,2,2,1].forEach(b => a.add(b));
for(let i of a) {
    console.log(i)
}
// 1 2 3 4

The Set function can accept an array (or other data of other iterable interfaces) as a parameter to initialize.

const set = new Set([1,2,3,4,5,4,3,2,1]);
[...set]
// [1, 2, 3, 4, 5]

No type conversion occurs when adding a value to the set, so 5 and '5' are two different values.

two objects are always unequal

let s = new Set();
s.add({}).add({});
s.size // 2

Properties and Methods of Set Instances

Instances of the set structure have the following methods:

  • Set.propotype.constructor: constructor, the default is the Set function
  • Set.prototype.size: returns the total number of members of the Set instance

The method of Set instance is divided into operation method and traversal method

Operation method:

  • add(value): Add a value and return the Set structure itself.
  • delete(value): Delete a value and return a Boolean value indicating success or failure.
  • has(value): Returns a Boolean value, indicating whether the parameter is a Set member.
  • clear(): clears all members, no return value.
let s = new Set();
s.add(1).add(2);
s.size // 2
s.delete(1) // true
s.has(1) // false
s.clear()
s.size // 0

Traverse operation:

  • keys: Returns a iterator of key names.
  • values: Returns a iterator for key values.
  • entries: Returns a iterator of key-value pairs.
  • forEach: use the callback function to traverse each member.

The order of Set traversal is the order of insertion

Since the Set structure has no key names, only key values. All keys methods behave exactly the same as values ​​methods.

let set = new Set(['red', 'green', 'blue']);
for (let key of set.keys()) {
    console.log(key)
};
// red green blue

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

for (let item of set.entries()) {
    console.log(item)
};
// ["red", "red"] ["green", "green"] ["blue", "blue"]

// for of 也可直接遍历Set
for (let item of set) {
    console.log(item)
};
// red green blue

let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2));
// 2 4 6

Convert the Set data structure to Array:

let set = new Set([1, 2, 3]);

// 方法一
Array.from(set);

// 方法二
[...set]

Applications traversed:

Extend operator and Set with deduplication

let arr = [1, 2, 3, 3, 4, 2, 1];
let set = [...new Set(arr)];
// [1, 2, 3, 4]

Using map and filter with the spread operator

let set = new Set([1, 2, 3]);
set = new Set([...set].map(a => a * 2));
// 2, 4, 6

intersection, union, difference

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

// 并集
let union = new Set([...a, ...b]);
// 1, 2, 3, 4, 5

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// 3

// 差集
let intersect = new Set([...a].filter(x => !b.has(x)));
// 1, 2

If you want to change the original Set structure synchronously during the traversal operation, there are only two workarounds.

let set = new Set([1, 2, 3]);

// 方法一
set = new Set([...set].map(x => x * 2));

// 方法二
set = new Set(Array.from(set, val => val * 2));

WeakSet

meaning

WeakSet is similar to Set and is also a collection of unique values. But he has two differences from Set:

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

consr ws = new WeakSet();
ws.add(1);
// 报错
ws.add(Symnol());
// 报错

2. The objects in the WeakSet are all weak references, that is, the garbage collection mechanism does not consider the WeakSet's reference to the object. That is to say, if other objects do not refer to the object, the garbage collection mechanism will automatically reclaim the memory occupied by the object, regardless of whether the object still exists in the WeakSet.

grammar

WeakSet is a constructor that can use the new command to create a WeakSet data structure.

const ws = new WeakSet()

As a constructor, WeakSet accepts an array or array-like object as a parameter. Objects with iterable interface can also be used as parameters of WeakSet.

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

const b = [3, 4];
const ws = new WeakSet(b);
// 报错,数组b的成员不是对象

The WeakSet structure has the following three methods:

  • WeakSet.prototype.add(value): Add members to the WeakSet instance
  • WeakSet.prototype.delete(value): Clear the specified member of the WeakSet instance
  • WeakSet.prototype.has(value): Returns a Boolean value indicating whether a value is in the WeakSet instance

WeakSet has no size property, and there is no way to iterate over its members.

Map

Meaning and Basic Usage

JavaScript objects are essentially a collection of key-value pairs, but only strings can be used as keys. ES6 provides a Map data structure, which is similar to objects, but any type of value can be used as a key (including objects).

const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content');
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

As a constructor, Map can also accept an array as a parameter, and the members of the array are arrays representing key-value pairs.

const map = new Map([
    ['name', '张三'],
    ['title', '提示']
]);
map.size //  2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "提示"

Set and Map can also be used to generate new Maps. (Any data structure that has an iterator interface and each member is a two-element array can be used as a parameter of the Map constructor)

If multiple assignments are made to the same key, later values ​​will overwrite earlier ones. Only references to the same object are considered the same key by the Map structure.

const map = new Map();
map.set(['a'], 555);
map.get(['a']); // undefined

Because the memory addresses of the two arrays are different, the get method cannot read the key and returns undefined.

Manipulation Methods for Instances and Properties

  • size attribute: returns the total number of members of the Map structure
  • set(key, value): Set the key value corresponding to the key, and then return the entire Map structure. If the key already has a value, the key value will be updated, otherwise, the key will be newly generated
  • get(key): read the key value corresponding to the key, if the key cannot be found, return undefined
  • has(key): Returns a Boolean value indicating whether a key is in the Map data structure
  • delete(key): Delete a key and return true. Delete failed, return false
  • clear(): Clear all members, no return value

traversal method

  • keys method: returns a traverser of key names
  • Values ​​method: returns a traverser of key values
  • entries method: returns a traverser of all members
  • forEach method: traverse all members of the Map

The order of Map traversal is the order of insertion

You can use for of to traverse directly, which is equivalent to map.entries()

It can also be converted into an array using the extension operator, and the traversal and filtering can be realized through the map method and the filter method.

Interconversion with other data structures

Map to array

const myMap = new Map()
  .set(true, 7)
  .set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]

Array to Map

new Map([
  [true, 7],
  [{foo: 3}, ['abc']]
])
// Map {
//   true => 7,
//   Object {foo: 3} => ['abc']
// }

Map to object

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

const myMap = new Map()
  .set('yes', true)
  .set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }

Object to Map

function objToStrMap(obj) {
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}

Map to JSON

function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'

function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'

JSON to Map

function jsonToStrMap(jsonStr) {
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}

function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

WeakMap

meaning

WeakMapStructs Mapare similar to structs and are also used to generate collections of key-value pairs.

// WeakMap 可以使用 set 方法添加成员
const wm1 = new WeakMap();
const key = {foo: 1};
wm1.set(key, 2);
wm1.get(key) // 2

// WeakMap 也可以接受一个数组,
// 作为构造函数的参数
const k1 = [1, 2, 3];
const k2 = [4, 5, 6];
const wm2 = new WeakMap([[k1, 'foo'], [k2, 'bar']]);
wm2.get(k2) // "bar"

WeakMap and Map have the following two differences

1. WeakMapOnly accept objects as keys ( nullexcept), and do not accept other types of values ​​as keys.

const map = new WeakMap();
map.set(1, 2)
// TypeError: 1 is not an object!
map.set(Symbol(), 2)
// TypeError: Invalid value used as weak map key
map.set(null, 2)
// TypeError: Invalid value used as weak map key

2. WeakMapThe object pointed to by the key name is not included in the garbage collection mechanism. The objects referenced by its key name are all weak references, that is, the garbage collection mechanism does not take the reference into consideration. Therefore, as soon as other references to the referenced object are cleared, the garbage collection mechanism will free the memory occupied by the object. That is to say, once it is no longer needed, the key name object and the corresponding key-value pair in the WeakMap will disappear automatically, and there is no need to manually delete the reference.

WeakMap syntax

There are two differences between WeakMap and Map methods

First, there is no traversal operation and no sizeattributes

Second, it cannot be cleared, that is, clearthe method is not supported.

WeakMapOnly four methods are available: get(), set(), has(), delete().

const wm = new WeakMap();

// size、forEach、clear 方法都不存在
wm.size // undefined
wm.forEach // undefined
wm.clear // undefined

 

Guess you like

Origin blog.csdn.net/Stark6/article/details/104101267