写点什么

Vue 进阶(贰零贰):集合 Set 和 Map

  • 2021 年 11 月 21 日
  • 本文字数:3974 字

    阅读完需:约 13 分钟

Vue进阶(贰零贰):集合 Set 和 Map

一、集合的概念

集合是由一组无序且唯一(元素不能重复)的项组成的。这个数据结构使用了与有限集合相同的数学概念,应用在计算机的数据结构中。特点:keyvalue相同,没有重复的value.

二、Set 集合

ES6提供了数据结构set,它类似于数组,但是成员的值都是唯一的,没有重复的值 。Set 本身是一个构造函数,用来生成 Set 数据结构。


Set数据结构的创建——Set方法里可以指定参数,也可以不指定参数(参数是一个数组)。


const s1 = new Set();const s2 = new Set([1,2,3,4]);
console.log(s1) // Set {}console.log(s2) // Set { 1, 2, 3, 4 }
复制代码


Set类的属性——获取Set类中有几个数据。


const s1 = new Set();const s2 = new Set([1,2,3,4]);
console.log(s1.size) // 0console.log(s2.size) // 4
复制代码


Set 类的方法—Set.add(value)——Set.add(value) 添加一个数据,返回 Set 结构本身


成员的值都是唯一的,没有重复的值,所以在后面添加相同的值到 set 结构中是无效的


s1.add('a').add('b');console.log(s1)   //Set { 'a', 'b' }
s2.add('c')console.log(s2); //Set { 1, 2, 3, 4, 'c' }
s2.add(1);console.log(s2); //已经有相同的值了,所以添加无效还是原来的 Set { 1, 2, 3, 4, 'c' }
复制代码


Set 类的方法—Set.delete(value) set.delete(value) 删除指定数据,返回一个布尔值,表示删除是否成功


const s2 = new Set([1,2,3,4]);
var ba1 = s2.delete(1)var ba2 = s2.delete('c')
console.log(ba1); //trueconsole.log(ba2); //falseconsole.log(s2); //Set { 2, 3, 4 }
复制代码


Set 类的方法—Set.has(value)——判断该值是否为 set 的成员,返回一个布尔值


const s = new Set([1,2,3,4]);
const bs1 = s.has(1);const bs2 = s.has('a');console.log(bs1,bs2); //true false
复制代码


Set 类的方法—Set.clear()——清除所有的数据,没有返回值


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


Set 的遍历器——keys() 返回键名的遍历器,values() 返回键值的遍历器,entries() 返回键值对的遍历器,forEach() 使用回调函数遍历每个成员


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

//该方法可以接收三个参数,分别是:键值,健名,set本身s.forEach(function(value,key,set){ console.log(value+'lina'); console.log(set)})
复制代码


利用 Set 为数组去重——直接将要给数组放入到,set构造方法中即可


const arr = [1,2,3,45,2,3,4,13,5,7,1,3,2]
const s = new Set(arr);
console.log(s); // Set { 1, 2, 3, 45, 4, 13, 5, 7 }console.log(arr); //[ 1, 2, 3, 45, 2, 3, 4, 13, 5, 7, 1, 3, 2 ]
console.log([...s]);//将set转成数组,结果是[ 1, 2, 3, 45, 4, 13, 5, 7 ]
复制代码

三、Map 数据结构

Map 数据结构概述 字典:是用来存储不重复 key 的 Hash 结构,不同于集合(Set)的是,字典使用的是[键,值]的形式来存储数据的


JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。


为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。


创建 Map 和 Map 类的属性——获取 Map 类中有几个数据


const  m = new Map([    ['a',1],    ['b',2]]);
console.log(m); //Map { 'a' => 1, 'b' => 2 }console.log(m.size); //2
复制代码


Map 类的方法—set(key,value) 设置键名 key 对应的键值为 value,然后返回整个 Map 结构,如果 key 已经有值,则键值会被更新,否则就生成该键


Map 类的方法—get(key)——get 方法读取 key 对应的键值,如果找不到 key,返回 undefined


const  m = new Map([    ['a',1],    ['b',2]]);
m.set('miaov','ketang').set('xing','huang');//因为返回的是Map结构本身,所以可以使用调用链的方式console.log(m);//Map { 'a' => 1, 'b' => 2, 'miaov' => 'ketang', 'xing' => 'huang' }

m.set('b',5);//有相同的key,值会被覆盖console.log(m); //Map { 'a' => 1, 'b' => 5, 'miaov' => 'ketang', 'xing' => 'huang' }
console.log(m.get('b')); //5console.log(m.get('c')); //undefined
复制代码


Map 类的方法—delete(key) 删除某个键,删除成功放回 true,如果删除失败,返回 false


const  m = new Map([    ['a',1],    ['b',2]]);
console.log(m.delete('b'));//trueconsole.log(m.delete('c'));//falseconsole.log(m);//Map { 'a' => 1 }
复制代码


Map 类的方法—has(key) 方法返回一个布尔值,表示某个键是否在当前 Map 对象之中


Map 类的方法—clear() 清楚 Map 结构中的所有数据,没有返回值


const  m = new Map([    ['a',1],    ['b',2]]);
console.log(m.has('b'));//trueconsole.log(m.has('c'));//false
m.clear();console.log(m);//Map {}
复制代码


Map 的遍历器 keys() 返回键名的遍历器;values() 返回键值的遍历器;entries() 返回键值对的遍历器;forEach() 使用回调函数遍历每个成员


const  m = new Map([    ['a',1],    ['b',2],    ['c',3]]);
console.log(m.keys());//MapIterator { 'a', 'b', 'c' }console.log(m.values()); //MapIterator { 1, 2, 3 }console.log(m.entries()); //MapIterator { [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] }
//该方法可以接收三个参数:值,键,Map本身m.forEach(function (value, key, Map) { console.log(value); console.log(key);})
复制代码


Map 在使用过程中的一些注意事项一两个 NaN 本身是不相等的,但在 Map 结构中,NaN 作为键的话,视为相等的(同一个键)


const  map = new Map();map.set(NaN,1);map.set(NaN,2);
console.log(map); //Map { NaN => 2 }
复制代码


Map 在使用过程中的一些注意事项二 如果 Map 结构中的 key 是一个对象的情况下,每个对象都是不同的键,即使是两个空的对象,因为两个对象的地址值不同,以后引用别人的插件,使用对象作为键,就能避免同名碰撞的情况


const map = new Map();
map.set({},'x').set({},'y');
console.log(map); //Map { {} => 'x', {} => 'y' }
复制代码


Map 结构转为数组结构——比较快速的方法是使用扩展运算符(...)。


const  m = new Map([    ['a',1],    ['b',2]]);
console.log([...m.keys()]); //[ 'a', 'b' ]console.log([...m.values()]); //[ 1, 2 ]console.log([...m.entries()]); //[ [ 'a', 1 ], [ 'b', 2 ] ]console.log([...m]); //[ [ 'a', 1 ], [ 'b', 2 ] ]
复制代码


数组结构转为 Map 结构——将数组传入 Map 构造函数,就可以转为 Map


const arr = [[1,'one'],[2,'two'],[3,'three']];
const map = new Map(arr);
console.log(map);//Map { 1 => 'one', 2 => 'two', 3 => 'three' }
复制代码


Map 结构转为对象——如果所有 Map 的键都是字符串,它可以转为对象


const myMap = new Map();
myMap.set('yes', true)myMap .set('no', false);console.log(myMap); //Map { 'yes' => true, 'no' => false }
const obj = strMapToObj(myMap);console.log(obj); //{ yes: true, no: false }
function strMapToObj(strMap) { let obj = Object.create(null); for (let [k,v] of strMap) { obj[k] = v; } return obj;}
复制代码


对象转为 Map 结构


function objToStrMap(obj) {    let strMap = new Map();    for (let k of Object.keys(obj)) {        strMap.set(k, obj[k]);    }    return strMap;}
const map = objToStrMap({yes: true, no: false});console.log(map); //Map { 'yes' => true, 'no' => false }
复制代码


Map 结构转为 JSON 对象 Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。 需要先将其转成对象


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

function strMapToObj(strMap) { let obj = Object.create(null); for (let [k,v] of strMap) { obj[k] = v; } return obj;}
let myMap = new Map().set('yes', true).set('no', false);console.log(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']);console.log(mapToArrayJson(myMap)); //[[true,7],[{"foo":3},["abc"]]]JSON转为Map结构——JSON 转为 Map,正常情况下,所有键名都是字符串
function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr));}
function objToStrMap(obj) { let strMap = new Map(); for (let k of Object.keys(obj)) { strMap.set(k, obj[k]); } return strMap;}
console.log(jsonToStrMap('{"yes": true, "no": false}')); //Map { 'yes' => true, 'no' => false }
复制代码


有一种特殊情况,整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。这时,它可以一一对应地转为 Map。这往往是数组转为 JSON 的逆操作。


function jsonToMap(jsonStr) {    return new Map(JSON.parse(jsonStr));}
console.log(jsonToMap('[[true,7],[{"foo":3},["abc"]]]')); //Map { true => 7, { foo: 3 } => [ 'abc' ] }
复制代码


发布于: 4 小时前阅读数: 4
用户头像

No Silver Bullet 2021.07.09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
Vue进阶(贰零贰):集合 Set 和 Map