ES6 Set和Map数据结构

一、Set

1.基本用法

Set数据类型类似数组,但里面的元素都是唯一的。

		var s = new Set();
        [2,2,3,4,3,2,2].forEach(x=>s.add(x));
        console.log(s);	//[2,3,4]

        const a = new Set([2,8,4,6,2,2,3]);
        console.log(a);	//[2,8,4,6,3]
        console.log("a的size:" + a.size);	//5
        console.log("-------------------------");

        const c = new Set(document.querySelectorAll('div'));
        console.log(c.size); 	//2,此时body有两个div
  • 去除数组重复成员:
        var array = [1,2,2,3,3,4,4,4,6];
        console.log([...new Set(array)]);//[1,2,3,4,6]
        console.log([...new Set(array)].join(''));//12346
  • 去除字符串重复字符:
console.log([...new Set("aabbccddee")].join(''));	//abcde

在Set内部认为两个NaN是相等的,而两个对象总是不同的。

        var d = new Set();
        d.add(NaN);
        d.add(NaN);
        console.log(d.size);		//1

        d.add({});
        d.add({});
        console.log(d.size);	//3

3.Set 实例的属性和方法

(1)两个属性

Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。

        var d = new Set();
        d.add(NaN);
        d.add(NaN);
        d.add({});
        d.add({});
        console.log(d.size);	//3
        console.log(d.constructor);	// ƒ Set() { [native code] }

(2)四个方法

Set.prototype.add(value):添加某个值,返回 Set 结构本身。
Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
Set.prototype.clear():清除所有成员,没有返回值。

        var e = new Set();
        e.add(1);
        e.add(2);
        e.add(3);
        e.delete(1);
        console.log(e);		//Set(2) {2, 3}
        console.log(e.has(1));	//false
        console.log(e.has(2));	//true
        e.clear();
        console.log(e);		//Set(0){}
  • Array.from() : 可以把Set结构转化为数组
const items = new Set([1, 2, 3, 4, 5]);
const array = Array.from(items);

3.遍历操作

(1)keys(),values(),entries()

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

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"]
  • Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。这意味着,可以省略values方法,直接用for…of循环遍历 Set。
		var g = new Set(["red","blue","green"]);
		for(let item of g)
        {
            console.log(item);
        }
        //red
		//blue
		//green

(2)forEach()

let set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9

(3)遍历的应用
1)去除数组的重复元素
2)数组的并集、交集、差集

二、WeakSet数据结构

WeakSet与set类似,不能有重复的值。与set的区别是,WeakSet的成员之能是对象,不能是其他类型的值。

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

(1)三个方法:

WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。
WeakSet没有size属性,所以没办法遍历所有成员。

三、Map

1.含义和基本用法

Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。

(1)方法:set(),get(),has(),delete(),
clear():清除所有成员

        const m = new Map();
        const o = {p:'HelloWorld'};
        m.set(o,'abc');
        console.log(m.get(o));		//abc
        console.log(m.has(o));		//true
        m.delete(o);	
        console.log(m.has(o));		//false

(2)用Map添加成员

        console.log(ws);
        console.log(ws.size);
        console.log(ws.has('name'));
        console.log(ws.get("name"));
        console.log(ws.has("age"));
        console.log(ws.get("age"));
  • Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。

如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map
将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然NaN不严格相等于自身,但
Map 将其视为同一个键。

		var m = new Map();
        m.set(0,111);
        m.set(-0,222);
        console.log(m.get(0));
        m.set(true,333);
        m.set("true",444);
        console.log(m.get("true"));
        console.log(m.get(true));
        m.set(undefined,5);
        m.set(null,6);
        console.log(m.get(undefined));
        console.log(m.get(null));
        m.set(NaN,7);
        m.set(NaN,8);
        console.log(m.get(NaN));
//打印的值
222
444
333
5
6
8

2.遍历方法

Map.prototype.keys():返回键名的遍历器。
Map.prototype.values():返回键值的遍历器。
Map.prototype.entries():返回所有成员的遍历器。
Map.prototype.forEach():遍历 Map 的所有成员。

        var m = new Map([
            ["one",111],
            ["two",222]
        ]);
        for(let key of m.keys()){
            console.log(key);
        }
        for(let value of m.values()){
            console.log(value);
        }
        for(let [key,value] of m.entries()){
            console.log(key,value);
        }
//打印结果:
one
two
111
222
one 111
two 222
one 111
two 222
  • 把Map结构转化为数组
        var m = new Map([
            ["one",111],
            ["two",222]
        ]);
        console.log([...m.keys()]);
        console.log([...m.values()]);
        console.log([...m.entries()]);
        console.log([...m]);
     	m.forEach(function(key,value){
            console.log("Key:%s,value:%s",key,value);
        })
//打印结果
["one", "two"]
[111, 222]
[["one",111],["two",222]]
[["one",111],["two",222]]
Key:111,value:one
Key:222,value:two

3.与其他数据类型的转换

(1)Map转换为数组:使用扩展运算符(…)。
(2)数组 转为 Map:将数组传入 Map 构造函数,就可以转为 Map
(3)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:通过Object.entries()。

        let obj = {"a":1, "b":2};
        let map = new Map(Object.entries(obj));
        console.log([...map]);
//打印结果
[["a", 1],["b", 2]]

(5)Map转换为JSON
1)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}'

2)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
1)所有键名都是字符串

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

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

2)整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组。

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

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

四、WeakMap

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

1.与Map的区别
(1)WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名。
(2)WeakMap的键名所指向的对象,不计入垃圾回收机制。

2.特点:元素一旦不再需要,WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。

3.WeakMap的用法:
WeakMap 与 Map 在 API 上的区别主要是两个,
(1)没有遍历操作(即没有keys()、values()和entries()方法)
(2)没有size属性。
(3)不可以使用clear()
(4)只能用get(),set(),has(),delete()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值