Set 和 Map

Set 结构

Set是es6中的一种新的数据结构,他的值都是唯一的,没有重复的值。但是键值和key都是相等的。通常可以用来去重数组,去掉字符串中相同的字符串、实现并集、交集、差集;

  • 给数组去重:
  let arr = [1,2,3,4,2,3,4,5];
  // 可以使用扩展运算符
  const setArr1 = [...new Set(arr)];
  // 也可使用Array.form将set数组结构转成数组
  const setArr2 = Array.from(new Set(arr))
  console.log(setArr1); // [1,2,3,4,5]
  console.log(setArr2); // [1,2,3,4,5]
  • 字符串去重:
 const str = 'abababc';
 const set = [...new Set(str)].jion('');
 console.log(set); // 'abc'
  • 实现并集、交集、差集
const a = new Set([1,2,3,7,5]);
const b = new Set([2,5,8,9,7]);
// 并集
const res1 = new Set([...a,...b])
console.log(res1); // {1,2,3,7,5,8,9}
// 交集
const res2 = new Set([...a].filter(x=>b.has(x)));
console.log(res2); // {2,7,5}
// 差集
const res3 = new Set([...a].filter(x=> !b.has(x)));
console.log(res3); // {1,3}
set的方法
  • add(): 添加set项
  • has(): 判断set中是否有改项
  • size(): set的长度
  • keys(): 返回键名
  • valuse(): 返回键值,跟键名值是一样的
  • entries(): 返回键值对
 const set = new Set(['red','green','pink']);
 for(let item of set.entries){
   console.log(item)
 }
 // ['red','red']
 // ['green','green']
 // ['pink','pink']
  • forEach():Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。
let set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9
WeakSet 结构

与 Set 类似,也是不重复的值的集合。但是,它与 Set 有两个区别。首先,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);
// Uncaught TypeError: Invalid value used in weak set(…)
Map结构

Map是es6新增的一种数据结构,他类似于对象,也是键值对的集合,但是键(key)的范围可以是任何数据类型(包括对象),不仅局限于字符串。Object结构键只能是字符串,有些场景比如键需要的是对象其他类型的,使用object就不能实现,如果需要键值对的数据结构,Map比Object更适合。

const map = new Map();
const arr = [1,23];
map.set(arr,'数组');
map.get(arr); // '数组'
const map = new Map([['name','张三'],['age','18']])
map.size; // 2
map.get('name');  // 张三
map.has('name'); // true
map.get('like'); // undefined
// 以上这种类似一下写法
const items = [['name','张三'],['age','18']];
const map1 = new Map();
items.forEach([key,value] = > map1.set(key,value))
  • Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。
let map = new Map();

map.set(-0, 123);
map.get(+0) // 123

map.set(true, 1);
map.set('true', 2);
map.get(true) // 1

map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3

map.set(NaN, 123);
map.get(NaN) // 123

map.set([1],'数组');
map.get([1]); // undefined 因为引用地址不一样
  • 对同一个键多次赋值,后面的值将覆盖前面的值。
const map = new Map();
map.set('1','qqq').set('1','aaa');
map.set('1');  // 'aaa'
  • Map 转成数组
 const map = new Map().set('key1','values1').set('key2','values2')
 const arr= [...map];
 console.log(arr); // [['key1','values1'],['key2','values2']]
  • 数组转成Map
const map = new Map([['key1','values1'],['key2','values2']]);
console.log(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 }
  • 对象转为 Map
let obj = {"a":1, "b":2};
let map = new Map(Object.entries(obj));
  • Map 转为 JSON
    键是字符串,使用JSON.stringfy
function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

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

键不是字符串,可转成数组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"]]]'
WeakMap

WeakMap结构与Map结构类似,也是用于生成键值对的集合。WeakMap与Map的区别有两点。

  • 首先,WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
const wm1 = new WeakMap();
const key = {foo: 1};
wm1.set(key, 2);
wm1.get(key) // 2

// 一下是错误
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
  • 其次,WeakMap的键名所指向的对象,不计入垃圾回收机制。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值