ES6——新增数据结构Set与Map的用法
ES6 提供了新的数据结构 Set以及Map,下面我们来一一讲解。
一、Set
特性
似于数组,但它的一大特性就是所有元素都是唯一的,没有重复。
我们可以利用这一唯一特性进行数组的去重工作。
1.单一数组的去重
let set6 = new Set([1, 2, 2, 3, 4, 3, 5])
console.log('distinct 1:', set6)
结果:
distinct 1: Set { 1, 2, 3, 4, 5 }
2.多数组的合并去重
let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let set7 = new Set([...arr1, ...arr2])
console.log('distinct 2:', set7)
结果:
distinct 2: Set { 1, 2, 3, 4, 5, 6 }
操作----------------------------------
1.add
let set1 = new Set() set1.add(1) set1.add(2) set1.add(3) console.log('added:', set1)
结果:
added: Set { 1, 2, 3 }
2.delete
let set1 = new Set()
set1.add(1)
set1.add(2)
set1.add(3)
set1.delete(1)
console.log('deleted:', set1)
结果:
deleted: Set { 2, 3 }
3.has
let set1 = new Set() set1.add(1) set1.add(2) set1.add(3) set1.delete(1) console.log('has(1):', set1.has(1)) console.log('has(2):', set1.has(2))
结果:
has(1): false
has(2): true
4.clear
let set1 = new Set()
set1.add(1)
set1.add(2)
set1.add(3)
set1.clear()
console.log('cleared:', set1)
结果:
cleared: Set {}
5.size属性
console.log("容器大小:",set.size); //4
6.Array 转 Set
let set2 = new Set([4,5,6])
console.log('array to set 1:', set2)
let set3 = new Set(new Array(7, 8, 9))
console.log('array to set 2:', set3)
结果:
array to set 2: Set { 4, 5, 6 }
array to set 3: Set { 7, 8, 9 }
7.Set 转 Array
let set4 = new Set([4, 5, 6])
console.log('set to array 1:', [...set4])
console.log('set to array 2:', Array.from(set4))
结果:
set to array 1: [ 4, 5, 6 ]
set to array 2: [ 4, 5, 6 ]
8.遍历(keys(),values(),entries())
可以使用Set实例对象的keys(),values(),entries()方法进行遍历。
由于Set的键名和键值是同一个值,它的每一个元素的key和value是相同的,所有keys()和values()的返回值是相同的,entries()返回的元素中的key和value是相同的。
let set5 = new Set([4, 5, 'hello']) console.log('iterate useing Set.keys()') for(let item of set5.keys()) { console.log(item) } console.log('iterate useing Set.values()') for(let item of set5.values()) { console.log(item) } console.log('iterate useing Set.entries()') for(let item of set5.entries()) { console.log(item) }
结果:
iterate useing Set.keys() 4 5 hello
iterate useing Set.values() 4 5 hello
iterate useing Set.entries() [ 4, 4 ] [ 5, 5 ] [ 'hello', 'hello' ]
注:在向Set加入值时,Set不会转换数据类型,内部在判断元素是否存在时用的类似于精确等于(===)的方法,“2”和2是不同的。
二、Map
Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是”字符串-值“对,属性只能是字符串,如果传个对象字面量作为属性名,那么会默认把对象转换成字符串,结果这个属性名就变成”[object Object]“。
ES6提供了”值-值“对的数据结构,键名不仅可以是字符串,也可以是对象。它是一个更完善的Hash结构。
特性
const map1 = new Map()
const objkey = {p1: 'v1'}
map1.set(objkey, 'hello')
console.log(map1.get(objkey))
结果:
hello
2.Map可以接受数组作为参数,数组成员还是一个数组,其中有两个元素,一个表示键一个表示值。
const map2 = new Map([
['name', 'Aissen'],
['age', 12]
])
console.log(map2.get('name'))
console.log(map2.get('age'))
结果:
Aissen
12
操作-------------------------------
1.size
获取map的大小。
const map3 = new Map();
map3.set('k1', 1);
map3.set('k2', 2);
map3.set('k3', 3);
console.log('%s', map3.size)
结果:
3
2.set
const map4 = new Map(); map4.set('k1', 6) // 键是字符串 map4.set(222, '哈哈哈') // 键是数值 map4.set(undefined, 'gagaga') // 键是 undefined const fun = function() {console.log('hello');} map4.set(fun, 'fun') // 键是 function console.log('map4 size: %s', map4.size) console.log('undefined value: %s', map4.get(undefined)) console.log('fun value: %s', map4.get(fun))
结果:
map4 size: 4
undefined value: gagaga
fun value: fun
也可对set进行链式调用。
map4.set('k2', 2).set('k3', 4).set('k4', 5)
console.log('map4 size: %s', map4.size)
结果:
map4 size: 7
3.get
获取键对应的值。
const map5 = new Map();
map5.set('k1', 6)
console.log('map5 value: %s', map5.get('k1'))
结果:
map5 value: 6
4.has
判断指定的键是否存在。
const map6 = new Map();
map6.set(undefined, 4)
console.log('map6 undefined: %s', map6.has(undefined))
console.log('map6 k1: %s', map6.has('k1'))
结果:
map6 undefined: true
map6 k1: false
5.delete
删除键值对。
const map7 = new Map();
map7.set(undefined, 4)
map7.delete(undefined)
console.log('map7 undefined: %s', map7.has(undefined))
结果:
map7 undefined: false
6.clear
删除map中的所有键值对。
const map8 = new Map(); map8.set('k1', 1); map8.set('k2', 2); map8.set('k3', 3); console.log('map8, pre-clear size: %s', map8.size) map8.clear() console.log('map8, post-clear size: %s', map8.size)
结果:
map8, pre-clear size: 3
map8, post-clear size: 0
遍历(keys(),values(),entries(),forEach())
提供三个新的方法 —— entries(),keys()和values() —— 用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
1.keys()
遍历map的所有key。
const map9 = new Map(); map9.set('k1', 1); map9.set('k2', 2); map9.set('k3', 3); for (let key of map9.keys()) { console.log(key); }
结果:
k1
k2
k3
2.values()
遍历map所有的值。
for (let value of map9.values()) {
console.log(value);
}
结果:
1 2 3
3.entries()
遍历map的所有键值对。
方法1:
for (let item of map9.entries()) {
console.log(item[0], item[1]);
}
结果:
k1 1
k2 2
k3 3
方法2:
for (let [key, value] of map9.entries()) {
console.log(key, value);
}
结果不变。
4.forEach()
遍历map的所有键值对。
map9.forEach(function(value, key, map) {
console.log("Key: %s, Value: %s", key, value);
});
结果:
Key: k1, Value: 1
Key: k2, Value: 2
Key: k3, Value: 3
forEach有第二个参数,可以用来绑定this。
这样有个好处,map的存储的数据和业务处理对象可以分离,业务处理对象可以尽可能的按职责分割的明确符合SRP原则。
const output = { log: function(key, value) { console.log("Key: %s, Value: %s", key, value); } }; map9.forEach(function(value, key, map) { this.log(key, value); }, output);
和其它结构的互转----------------------
1.Map 转 Array
使用扩展运算符三个点(...)可将map内的元素都展开的数组。
const map10 = new Map();
map10.set('k1', 1);
map10.set('k2', 2);
map10.set('k3', 3);
console.log([...map10]); //Array.from(map10)
结果:
[ [ 'k1', 1 ], [ 'k2', 2 ], [ 'k3', 3 ] ]
2.Array 转 Map
使用数组构造Map。
const map11 = new Map([
['name', 'Aissen'],
['age', 12]
])
console.log(map11)
结果:
Map { 'name' => 'Aissen', 'age' => 12 }
3.Map 转 Object
写一个转换函数,遍历map的所有元素,将元素的键和值作为对象属性名和值写入Object中。
function mapToObj(map) { let obj = Object.create(null); for (let [k,v] of map) { obj[k] = v; } return obj; } const map12 = new Map() .set('k1', 1) .set({pa:1}, 2); console.log(mapToObj(map12))
结果:
{ k1: 1, '[object Object]': 2 }
4.Object 转 Map
同理,再写一个转换函数便利Object,将属性名和值作为键值对写入Map。
function objToMap(obj) { let map = new Map(); for (let k of Object.keys(obj)) { map.set(k, obj[k]); } return map; } console.log(objToMap({yes: true, no: false}))
结果:
Map { 'yes' => true, 'no' => false }
5.Set 转 Map
const set = new Set([
['foo', 1],
['bar', 2]
]);
const map13 = new Map(set)
console.log(map13)
结果:
Map { 'foo' => 1, 'bar' => 2 }
6.Map 转 Set
function mapToSet(map) { let set = new Set() for (let [k,v] of map) { set.add([k, v]) } return set; } const map14 = new Map() .set('k1', 1) .set({pa:1}, 2); console.log(mapToSet(map14))
结果:
Set { [ 'k1', 1 ], [ { pa: 1 }, 2 ] }
例子
/* 1. Map和数组的使用 */ let map = new Map(); let array = []; //1.增 map.set('t', 1); array.unshift({ 't': 1 }); console.info(map, array); //2.查 let map_exist = map.has('t'); let array_exist = array.find(item => item.t); console.info(map_exist, array_exist); //3.改 map.set('t', 3); array.forEach(item => item.t ? item.t = 5 : ''); console.info(map, array); //4.删 map.delete('t'); let index = array.findIndex(item => item.t); array.splice(index, 1); console.info(map, array); /* 2. Set和数组的使用 */ let set = new Set(); let array = []; //1.增 set.add({ a: 1 }); array.push({ a: 1 }); console.info(set, array); //查 let set_exist = set.has({ a: 1 }); let array_exist = array.find(item => item.a); console.info(set_exist, array_exist); //改 set.forEach(item => item.a ? item.a = 3 : ''); array.forEach(item => item.a ? item.a = 5 : ''); console.info(set, array); //删 //set.forEach(item=>item.a?set.delete(item):''); set.forEach(item => item.a ? set.delete(item) : ''); let index = array.findIndex(item => item.a); array.splice(index, 1); console.info(set, array); /* 3. Map和Set以及对象的使用 */ let item = { t: 1 }; let map = new Map(); let set = new Set(); let obj = {}; //增 map.set('t', 1); set.add(item); obj['t'] = 1; console.info(map, set, obj); //查 console.info({ map_exist: map.has('t'), set_exist: set.has(item), obj_exist: 't' in obj }) //改 map.set('t', 3); set.forEach(item => item.t ? item.t = 5 : ''); obj['t'] = 6; console.info(map, set, obj); //删 map.delete('t'); set.delete(item); delete obj['t']; // arr.splice(index,1); console.info(map, set, obj);
原文来源:https://www.cnblogs.com/kongxianghai/p/7309735.html
entries(),keys()和values()