JS-学习ES6之- Set & Map 的数据结构

目录

  • Set
  • Map

1. Set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

1.1 基本用法

Set 本身是一个构造函数,用来生成 Set 数据结构。Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

cosnt set = new Set([1, 2, 3, 4, 4]);
[...set]; // [1, 2, 3, 4]

Set 加入值的时候,不会发生类型转换,所以5和”5”是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),但是在 Set 内部,两个NaN是相等。

let set = new Set();
let a = NaN;
let b = NaN;

set.add(a);
set.add(b);

[...set] // [NaN]

1.2 Set 实例的属性和方法

Set 实例的属性

  • size: 返回实例的成员总数;
  • constructor: 构造函数,默认是 Set 函数

Set 实例的方法

  • add(value): 添加值,返回 Set 结构本身
  • delete(value): 删除某个值,返回布尔值,表示删除是否成功
  • has(value): 返回布尔值,表示该值是否为 Set 的成员
  • clear(): 清楚所有成员,没有返回值
  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

Array.from方法可以将 Set 结构转为数组。
去除数组重复成员的另一种方法。

function dedupe(arr){
    return Array.from(new Set(arr));
}

dedupe([1, 1, 2, 3]); // [1, 2, 3]

由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

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"]

1.3 用途

使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].fliter(x => b.has(x)));
// Set {2, 3}

// 差集
let difference = new Set([...a].fliter(x => !b.has(x)));
// Set {1, 4}

2. Map

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

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

2.1 基本用法

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

Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

const map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);

map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author

2.2 实例的属性和操作方法

Set 实例的属性

  • size: 返回实例的成员总数;

Set 实例的方法

  • set(key, value): 设置键名key对应的键值为value,返回 Map 结构本身
  • get(key): get方法读取key对应的键值
  • delete(key): 删除某个键,返回布尔值,表示删除是否成功
  • has(value): 返回布尔值,表示某个键是否在当前 Map 对象之中
  • clear(): 清楚所有成员,没有返回值
  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

set 方法返回的是当前的Map对象,因此可以采用链式写法。

let map = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');

2.3 与其他数据结构的互相转换

Map 转为数组

Map 转为数组最方便的方法,就是使用扩展运算符

const map = new Map()
.set(true, 7)
.set({foo: 3}: ['bac']);

[...map] // [[true, 7], [{foo: 3}, ['bac']]]

数组转为 Map

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

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

Map 转为对象

如果所有 Map 的键都是字符串,它可以无损地转为对象。如果键表示字符串,那么键名会被转成字符串。

function mapToObj(strMap) {
    let obj = {};
    for(let [k, v] of strMap){
        obj[k] = v;
    }
    return obj;
}

const map = new Map().set('yes', true).set('no', false);

mapToObj(map); 
// {yes: true, no: false}

猜你喜欢

转载自blog.csdn.net/zhq2005095/article/details/80561478