Published 2021-11-20

Sets & Maps

Sets

Sets对象是值的集合,它不允许重复的值,并且是无序的。

// 创建 Set 对象
const emptySet = new Set()
// 添加元素到 Set 对象
emptySet.add('red').add('green').add('blue')
// 移除元素
emptySet.delete('red')
// 检查是否包含某个值
emptySet.has('green') // true
// 清除所有元素
emptySet.clear()
// 迭代 Set 对象
for (let item of emptySet) {
  console.log(item) // 'green', 'blue'
}
// 将 Set 对象转换为数组
;[...emptySet] // ['green', 'blue']
Array.from(emptySet) // ['green', 'blue']

去重

Array.from(new Set(['red', 'green', 'blue', 'red', 'green', 'blue'])) // ['red', 'green', 'blue']

创建一组 Unicode 字符

new Set('abc')
new Set(['a', 'b', 'c'])
assert.deepEqual(new Set('abc'), new Set(['a', 'b', 'c'])) // true

与映射键一样,Set元素与===进行比较,唯一不同的是NaN等于自身,但是object不等于自身。

const set = new Set([NaN, NaN, NaN]) // Set { NaN }
set.size // 1
set.has(NaN) // true

const set2 = new Set()
set2.add({})
set2.size === 1 // true
set2.add({})
set2.size === 2 // true

合并两个 Set

计算两个集合 a 和 b 的并集意味着创建一个包含 a 和 b 元素的集合。

const a = new Set([1, 2, 3]) // Set { 1, 2, 3 }
const b = new Set([4, 3, 2]) // Set { 2, 3, 4 }
const union = new Set([...a, ...b]) // Set { 1, 2, 3, 4 }

Set 的交集

计算两个集合 a 和 b 的交集意味着创建一个集合,其中包含 a 中也在 b 中的元素。

const a = new Set([1, 2, 3]) // Set { 1, 2, 3 }
const b = new Set([4, 3, 2]) // Set { 2, 3, 4 }
const intersection = new Set(Array.from(a).filter((x) => b.has(x))) // Set { 2, 3 }

Set 的差集

计算两个集合 a 和 b 之间的差意味着创建一个集合,其中包含不在 b 中的 a 元素。此操作有时也称为减号(−).

const a = new Set([1, 2, 3]) // Set { 1, 2, 3 }
const b = new Set([4, 3, 2]) // Set { 2, 3, 4 }
const difference = new Set(Array.from(a).filter((x) => !b.has(x))) // Set { 1 }

遍历 Set

Set 没有 map 方法

const set = new Set([1, 2, 3]) // Set { 1, 2, 3 }
const mappedSet = new Set(Array.from(set).map((x) => x * 2)) // Set { 2, 4, 6 }

过滤 Set

Set 没有 filter 方法

const set = new Set([1, 2, 3, 4, 5]) // Set { 1, 2, 3, 4, 5 }
const filteredSet = new Set(
  Array.from(set).filter((x) => x % 2 === 0) // Set { 2, 4 }
)

Maps

Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。

一个 Map 对象在迭代时会根据对象中元素的插入顺序来进行 — 一个 for...of 循环在每次迭代后会返回一个形式为[key,value]的数组。

创建 Map 对象

const emptyMap = new Map() // Map {}
emptyMap.size === 0 // true

// 添加键值对
emptyMap.set('foo', 'bar') // Map { 'foo' => 'bar' }

// 复制一个 Map 对象
const copy = new Map(emptyMap) // Map { 'foo' => 'bar' }

//获取键值对
emptyMap.get('foo') // 'bar'

//判断是否存在某个键
emptyMap.has('foo') // true

// 删除键值对
emptyMap.delete('foo') // true
emptyMap.has('foo') // false

// 获取Map对象大小
emptyMap.size // 0

// 删除所有键值对
emptyMap.clear() // Map {}

遍历 Map

const map = new Map().set(false, 'no').set(true, 'yes') // Map { false => 'no', true => 'yes' }
for (const key of map.keys()) {
  console.log(key) // false, true
}

entries() 方法返回一个新的包含 [key, value] 对的 Iterator 对象,返回的迭代器的迭代顺序与 Map 对象的插入顺序相同。

const map = new Map().set(false, 'no').set(true, 'yes') // Map { false => 'no', true => 'yes' }
for (const entry of map.entries()) {
  console.log(entry) // [false, 'no'], [true, 'yes']
}

keys() 返回一个引用的 Iterator 对象。它包含按照顺序插入 Map 对象中每个元素的 key 值。

const map = new Map([
  ['a', 1],
  ['b', 2]
])
map.keys() // MapIterator { 'a', 'b' }

values() 方法返回一个新的 Iterator 对象。它包含按顺序插入 Map 对象中每个元素的 value 值。

const map = new Map([
  ['a', 1],
  ['b', 2]
])
map.values() // MapIterator { 1, 2 }

合并两个 Map 对象

const map1 = new Map().set(1, '1a').set(2, '1b').set(3, '1c') // Map { 1 => '1a', 2 => '1b', 3 => '1c' }
const map2 = new Map().set(2, '2b').set(3, '2c').set(4, '2d') // Map { 2 => '2b', 3 => '2c', 4 => '2d' }
const map3 = new Map(map1).set(4, '2d') // Map { 1 => '1a', 2 => '2b', 3 => '2c', 4 => '2d' }