关于拥有Iterator接口的两种数据结构Set和Map,它们其实有很多相似的地方,这就是为什么ES6此书将两者整合为一章节进行讲解。并且两者对于实际开发,在对数据处理的过程中,确实存在比较实用的几点。
Set
特点一、接收拥有Iterator接口数据结构体作为参数,初始化Set
const arr = [1, 2, 3, 3, 4, 4]
const str = 'burnurn'
const map = new Map([[1, 'first'], [2, 'second']])
console.log(new Set(arr)) // Set(4) {1, 2, 3, 4}
console.log(new Set(str)) // Set(4) {"b", "u", "r", "n"}
console.log(new Set(map)) // Set(2) {Array(2), Array(2)}
特点二·、拥有Iterator接口,可以被for…of遍历
const arr1 = [1, 2, 3, 3, 4, 4]
const set1 = new Set(arr1)
for (const item of set1) {
console.log(item) // 1, 2, 3, 4
}
特点三、Set没有相关的方法用于操作内部的单独的某个值
自我结论:所以它的存在是一种对数据做某些处理比如:去重,用于储存数据的临时的数据结构体。
特点四、Set内部没有重复值
原由:因为Set结构的键名和键值是相同的,这就导致内部值具有唯一性
作用:为数组和字符串去重
// 简单示例
const arr = [1, 2, 3, 3, 4, 4]
const str = 'burnurn'
console.log(Array.from(new Set(arr))) // [1, 2, 3, 4]
console.log([...new Set(str)].join('')) // burn
// 场景:找出数组重复元素
const arr = [1, 2, 3, 3, 4, 5, 5, 3]
const repeatArr = []
arr.forEach(item => {
// 判断被检索元素在原数组中的出现的开始位置索引与最后出现的位置索引是否相同
if (arr.indexOf(item) !== arr.lastIndexOf(item)) {
// 存储重复值
repeatArr.push(item)
}
})
// 利用Set数据结构对存储重复值数组去重
const result = Array.from(new Set(repeatArr))
console.log(result)
特点五、实现数组的并、交、差集
const arr1 = [1, 2, 3, 3, 4, 4]
const arr2 = [1, 4, 5, 7, 8, 10]
const set1 = new Set(arr1)
const set2 = new Set(arr2)
// 并集
console.log(Array.from(new Set([...set1, ...set2]))) // [1, 2, 3, 4, 5, 7, 8, 10]
// 交集
console.log([...set1].filter(item => set2.has(item))) // [1, 4]
// 差集
console.log([...set1].filter(item => !set2.has(item))) // [2, 3]
特点六、相关属性和方法
属性:
Set.prototype.constructor
:构造函数,默认就是Set函数。
Set.prototype.size
:返回Set实例的成员总数。
操作方法:
Set.prototype.add(value)
:添加某个值,返回 Set 结构本身。
Set.prototype.delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。
Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set的成员。
Set.prototype.clear()
:清除所有成员,没有返回值。
遍历方法:
Set.prototype.keys()
:返回键名的遍历器
Set.prototype.values()
:返回键值的遍历器
Set.prototype.entries()
:返回键值对的遍历器
Set.prototype.forEach()
:使用回调函数遍历每个成员
Map
特点一、数据结构形式的更改
数据结构形式类似二维数组,[[key1, value1], [key2, value2]]
,其中键名不再像Object限制为字符串,而是可以为六大数据类型【包括基本数据类型和引用数据类型】,简称“值对值”。
注意:当键名为引用类型时,判断是否相同是其引用指针是否在内存为同一个地址
const second = []
const map = new Map([
[[], 'first'],
])
map.set(second, 'second')
console.log(map.get([]) , map.get(second)) // undefined "second"
特点二、拥有Iterator接口,可以被for…of遍历
const second = []
const map = new Map([
['first', 'first'],
])
map.set(second, 'second')
// 数组的解构[key, value] = item
for (const [key, value] of map) {
console.log(key) // first, []
console.log(value) // first, second
}
特点三、Map与其他数据结构的转化
1、数组Map转化
// 数组转map
const arrTomap = new Map([
['first', 'first'],
['second', 'second'],
])
// Map转数组
const mapToarr = [...arrTomap]
console.log(arrTomap) // Map(2) {"first" => "first", "second" => "second"}
console.log(mapToarr) // [['first', 'first'], ['second', 'second']]
2、对象Map转化
const map = new Map([
['first', 'first'],
[{}, 'second'],
])
// Map转对象
const mapToObject = map => {
const result = {}
for (const [key, value] of map ) {
result[key] = value
}
return result
}
const changeObject = mapToObject(map)
// 对象转Map
const objectToMap = object => {
const result = new Map()
for (const key in object) {
result.set(key, object[key])
}
return result
}
const changeMap = objectToMap(changeObject)
console.log(changeObject) // {first: "first", [object Object]: "second"}
console.log(changeMap) // Map(2) {"first" => "first", "[object Object]" => "second"}
3、JSON Map转化
const strMap = new Map([
['first', 'first'],
])
const objMap = new Map([
[{}, 'second'],
])
const mapToObject = map => {
const result = {}
for (const [key, value] of map ) {
result[key] = value
}
return result
}
const objectToMap = object => {
const result = new Map()
for (const key in object) {
result.set(key, object[key])
}
return result
}
// Map转Json
const mapToJson = data => JSON.stringify(data)
const changeJson = mapToJson(mapToObject(strMap))
const changeArrJson = mapToJson([...objMap])
// Json转Map
const jsonToMap = data => {
const params = JSON.parse(data)
return params instanceof Array ? new Map(params) : objectToMap(params)
}
const changeStrMap = jsonToMap(changeJson)
const changeObjMap = jsonToMap(changeArrJson)
console.log(changeJson) // Map转对象Json {"first":"first"}
console.log(changeArrJson) // Map转数组Json [[{},"second"]]
console.log(changeStrMap) // 对象Json转Map Map(1) {"first" => "first"}
console.log(changeObjMap) // 数组Json转Map Map(1) {{…} => "second"}
拓展
关于JSON对象就只有两种方法,且二者都支持参数回调函数,用于对被序列对象的相关操作
1、JSON.stringify():引用基本类型【对象/数组】序列化为JSON
2、JSON.stringify():JSON解析为引用基本类型【对象/数组】