1. set:{}

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

Set 本身是一个构造函数,用来生成 Set 数据结构。

const s = new Set();
 
[2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x));
 
for (let i of s) {
  console.log(i);
}
// 2 3 5 4

上面代码通过add方法向 Set 结构加入成员,结果表明Set 结构不会添加重复的值。

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

2.Set的应用场景

数组去重:

2.1
[...new Set(array)] 使用扩展运算符(内部使用for…of循环)将集合元素展开,再放进数组格式的结构里面
2.2

function dedupe(array) {
  return Array.from(new Set(array));
}
 
dedupe([1, 1, 2, 3]) // [1, 2, 3]

Array.from方法是将其他对象的格式转换成数组格式

3、Set 实例的方法

Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。
3.1先介绍四个操作方法:
add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。

<script>
     const s = new Set();
     s.add(1).add(2).add(2);
    // 注意2被加入了两次
 
    console.log(s.size); // 2
    console.log(s.has(1));// true
    console.log(s.delete(2));// true
    s.clear();
    console.log(s.size);//0
    </script>

3.2Set 实例的四个遍历方法
Set 结构的实例的四个遍历方法,可以用于遍历成员。
由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
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。

let set = new Set(['red', 'green', 'blue']);
 
for (let x of set) {
  console.log(x);
}
// red
// green
// blue

forEach方法,用于对每个成员执行某种操作,没有返回值。

let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6

使用 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].filter(x => b.has(x)));
// set {2, 3}
 
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

4、 Map

Set类似于数组,而Map就类似于键值对(Key, Value);

ES6 提供了 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"

Map构造函数实际上执行的是下面的算法:

const items = [
  ['name', '张三'],
  ['title', 'Author']
];
 
const map = new Map();
 
items.forEach(
  ([key, value]) => map.set(key, value)
);

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

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有size()属性:查看Map对象大小,set(key , value) , get(Key), delete(key) , has(key) ,clear()方法。
Map 结构原生提供三个遍历器生成函数(Map 的遍历顺序就是插入顺序)和一个遍历方法。

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

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);
 
for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"
 
for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"
 
for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"
 
// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"
 
// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

散列表
关于散列表的定义,这里摘抄一下维基百科的解释:

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

可以理解为,数据中的键通过一个散列函数的计算后返回一个数据存放的地址,因此可以直接通过地址来访问它的值,这样的查找就非常快。