Home > Article > Web Front-end > Analysis of Set and Map in ES6, and conversion between Map and other data structures
The content of this article is about the analysis of Set and Map in ES6, and the conversion between Map and other data structures. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you. help.
ES6 provides a new data structure─Set. It is similar to an array, but the values of the members are unique and there are no duplicate values.
Set itself is a constructor used to generate Set data structure.
Comparison between Array and Set
Both are containers that store multiple values. The two can be converted into each other, but there are differences in usage scenarios. As follows:
①The indexOf method of Array is less efficient than the has method of Set
②Set does not contain duplicate values (you can use this feature to achieve deduplication of an array)
③Set deletes a certain value through the delete method, and Array can only be passed through splice. The former is better in terms of convenience of use.
④ Many new methods of Array, such as map, filter, some, every, etc., are not available in Set (but they can be converted to each other for use)
let set = new Set(); set.add(1); set.add("1"); console.log(set.size); // 2
You can use an array to initialize a Set, and the Set constructor will ensure that these values are not used repeatedly:
let set = new Set([1, 2, 3, 4, 5, 5, 5, 5]); console.log(set.size); // 5
add(value): Add a value and return the Set structure itself
has(value): Return a Boolean value indicating whether the value is a member of the Set
let set = new Set(); set.add(1); set.add("1"); console.log(set.has(1)); // true console.log(set.has(6)); // false
delete(value): Delete a value and return a Boolean value, indicating whether it is successful or not
clear(value):Clear all members, no return value
let set = new Set(); set.add(1); set.add("1"); console.log(set.has(1)); // true set.delete(1); console.log(set.has(5)); // false console.log(set.size); // 1 set.clear(); console.log(set.size); // 0
keys():Returns the traverser of key names
values(): Returns the traverser of key-value pairs
entries():Returns a traverser of key-value pairs
forEach(): Each member
let set = new Set(['red', 'green', 'blue']); for (let item of set.keys()) { console.log(item); } // red // green // blue for (let item of set.values()) { console.log(item); } // red // green // blue for (let item of set.entries()) { console.log(item); } // ["red", "red"] // ["green", "green"] // ["blue", "blue"]
forEach()
let set = new Set([1, 2]); set.forEach(function(value, key, ownerSet) { console.log(key + ": " + value); }); // 输出
// 1: 1
// 2: 2
let arr = [1, 2, 2, 3]; let set = new Set(arr); let newArr = Array.from(set); console.log(newArr); // [1, 2, 3]
Set collection into Array array
let set = new Set([1, 2, 3, 3, 4]); let arr = Array.from(set) //输出[1,2,3,4]
The WeakSet structure is similar to Set, and it has Two differences:
①The members of weakSet can only be objects, not values of other types;
②weakSet objects are all weak references. If other objects no longer reference the object, the garbage collection mechanism will automatically reclaim the memory occupied by the object, so WeakSet is not traversable.
The WeakSet structure has the following three methods:
WeakSet.prototype.add(value): Add a new member 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 a WeakSet instance.
One use of WeakSet is to store DOM nodes without worrying about memory leaks when these nodes are removed from the document.
JavaScript object (Object) is essentially a collection of key-value pairs (Hash structure) , but traditionally only strings can be used as keys. This brings great limitations to its use.
ES6 provides the Map data structure. It is similar to an object and is also a collection of key-value pairs, but the scope of "key" is not limited to strings. Various types of values (including objects) can be used as keys. In other words, the Object structure provides "string-value" correspondence, and the Map structure provides "value-value" correspondence, which is a more complete implementation of the Hash structure.
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
The above code uses the set method of the Map structure to treat object o as a key of m, then uses the get method to read the key, and then uses the delete method to delete the key.
Attributes and operation methods of instances§ ⇧
1.size attribute
size Property returns the total number of members of the Map structure.
const map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2
2.set(key, value)
The set method sets the key value corresponding to the key name key to value, and then returns the entire Map structure. If the key already has a value, the key value will be updated, otherwise the key will be newly generated.
const m = new Map(); m.set('edition', 6) // 键是字符串 m.set(262, 'standard') // 键是数值 m.set(undefined, 'nah') // 键是 undefined
The set method returns the current Map object, so chain writing can be used.
let map = new Map() .set(1, 'a') .set(2, 'b') .set(3, 'c');
3.get(key)
The get method reads the key value corresponding to the key. If the key cannot be found, undefined is returned.
const m = new Map(); const hello = function() {console.log('hello');}; m.set(hello, 'Hello ES6!') // 键是函数 m.get(hello) // Hello ES6!
4.has(key)
Thehas method returns a Boolean value indicating whether a key is in the current Map object.
const m = new Map(); m.set('edition', 6); m.set(262, 'standard'); m.set(undefined, 'nah'); m.has('edition') // true m.has('years') // false m.has(262) // true m.has(undefined) // true
5.delete(key)
The delete method deletes a key and returns true. If deletion fails, return false.
const m = new Map(); m.set(undefined, 'nah'); m.has(undefined) // true m.delete(undefined) m.has(undefined) // false
6.clear()
The clear method clears all members and has no return value.
let map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2 map.clear() map.size // 0
Map 结构原生提供三个遍历器生成函数和一个遍历方法:
keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。
需要特别注意的是,Map 的遍历顺序就是插入顺序。
const map = new Map([ ['F', 'no'], ['T', 'yes'], ]); for (let key of map.keys()) { console.log(key); } // "F" // "T" for (let value of map.values()) { console.log(value); } // "no" // "yes" for (let item of map.entries()) { console.log(item[0], item[1]); } // "F" "no" // "T" "yes" // 或者 for (let [key, value] of map.entries()) { console.log(key, value); } // "F" "no" // "T" "yes" // 等同于使用map.entries() for (let [key, value] of map) { console.log(key, value); } // "F" "no" // "T" "yes"
WeakMap结构与Map结构类似,也是用于生成键值对的集合。
// 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与Map的区别有两点:
首先,WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
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
上面代码中,如果将数值1和Symbol值作为 WeakMap 的键名,都会报错。其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。
WeakMap的设计目的在于,有时我们想在某个对象上面存放一些数据,但是这会形成对于这个对象的引用。请看下面的例子。
const e1 = document.getElementById('foo'); const e2 = document.getElementById('bar'); const arr = [ [e1, 'foo 元素'], [e2, 'bar 元素'], ];
上面代码中,e1和e2是两个对象,我们通过arr数组对这两个对象添加一些文字说明。这就形成了arr对e1和e2的引用。一旦不再需要这两个对象,我们就必须手动删除这个引用,否则垃圾回收机制就不会释放e1和e2占用的内存。
// 不需要 e1 和 e2 的时候 // 必须手动删除引用 arr [0] = null; arr [1] = null;
1.Map 转为数组:
Map 转为数组最方便的方法,就是使用扩展运算符(...)。
const myMap = new Map() .set(true, 7) .set({foo: 3}, ['abc']); [...myMap] // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
2.数组 转为 Map:
将数组传入 Map 构造函数,就可以转为 Map。
new Map([ [true, 7], [{foo: 3}, ['abc']] ]) // Map { // true => 7, // Object {foo: 3} => ['abc'] // }
3.Map 转为对象:
如果所有 Map 的键都是字符串,它可以转为对象。
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 }
4.对象转为 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}
5.Map 转为 JSON:
Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 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}'
另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON。
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"]]]'
6.JSON 转为 Map:
JSON 转为 Map,正常情况下,所有键名都是字符串。
function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr)); } jsonToStrMap('{"yes": true, "no": false}') // Map {'yes' => true, 'no' => false}
但是,有一种特殊情况,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是数组转为 JSON 的逆操作。
function jsonToMap(jsonStr) { return new Map(JSON.parse(jsonStr)); } jsonToMap('[[true,7],[{"foo":3},["abc"]]]') // Map {true => 7, Object {foo: 3} => ['abc']}
The above is the detailed content of Analysis of Set and Map in ES6, and conversion between Map and other data structures. For more information, please follow other related articles on the PHP Chinese website!