ES6-Set和Map数据结构

Set数据结构

SetES6提供的一种新的数据结构,类似于数组,但是成员值都是唯一的,没有重复值;
Set本身就是一个构造函数,用来生成Set数据结构

// 示例一 通过add方法添加元素
var s = new Set();
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));
for (let i of s) {
  console.log(i); // 2, 3, 5, 4
}

// 示例二 参数形式初始化元素
var s = new Set([1, 2, 2, 3, 4, 5, 5, 6])
console.log([...s]) // 1, 2, 3, 4, 5, 6

Set实例的属性和方法

属性

  • Set.prototype.constructor构造函数,默认就是构造函数
  • Set.size 返回Set示例的成员总数
var set = new Set([1, 2, 3, 4])
console.log(Set.prototype.constructor === Set) // true
console.log(set.size) // 4

方法

  • add(value) 添加某个值,返回Set数据结构本身
var set = new Set()
set.add(1)
set.add(2)
set.add(1)
for(let i of set) {
    console.log(i) // 1, 2
}
  • delete(value) 删除某个值,返回一个布尔值,表示删除是否成功
var set = new Set([1, 2, 3, 5])
console.log(set.delete(1)) // true
console.log(set.delete(4)) // false
  • has(value) 返回一个布尔值,表示该值是否为Set的成员
// Object结构
var user = {
    name: 'xx'
    age: 12
}
// 判断是否存在某个属性
// if (user['name']) {
//     // do something
// }

// Set结构
var set = new Set([1, 2, 3, 5])
console.log(set.has(1)) // true
console.log(set.has(4)) // false
  • clear() 清除所有成员,没有返回值
var set = new Set([1, 2, 3, 4])
console.log(set.size) // 4
set.clear()
console.log(set.size) // 0

Set结构的遍历操作

由于Set结构没有键名,只有键值(或者说键名和键值是同一个值)
Set结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法

keys() values() entries()

  • keys() 返回键名的遍历器
  • values() 返回键值的遍历器
  • entries() 返回键值对的遍历器
var set = new Set(['red', 'green', 'blue'])
console.log(Set.prototype[Symbol.iterator] === Set.prototype.values) // true

// keys
for (let item of set.keys()) {
    console.log(item) // red green blue
}

// values
for (let item of set.values()) {
    console.log(item) // red green blue
}

// entries
for (let item of set.entries()) {
    console.log(item)
    // ['red', 'red']
    // ['green', 'green']
    // ['blue', 'blue']
}

// 直接遍历set示例
for (let x of set) {
  console.log(x); // red green blue
}

forEach()

  • 使用回调函数遍历每个成员,用于对每个成员执行某种操作,没有返回值
var set = new Set([1, 2, 3, 4, 5])
set.forEach(s => {
    console.log(s * 2) // 2, 4, 6, 8, 10
})

遍历的应用

数组去重

  • 采用同值相等的比较方法 NaN === NaN
  • 引用类型的数据永远不相等 {} !== {}
// 方式一 set + ...拓展运算符
var set = new Set([1, 2, 3, 3, 4, 5, 6, 6])
var unique = [...set];
cnosole.log(unique) // [1, 2, 3, 4, 5, 6]

// 方式二 set + Array.from函数
var set = new Set([1, 2, 3, 3, 4, 5, 6, 6])
var unique = Array.from(set)
console.log(unique) // [1, 2, 3, 4, 5, 6]

// 同值相等
var set = new Set([1, 2, 3, NaN, NaN, {}, {}])
var unique = [...set]
console.log(unique) // [1, 2, 3, NaN, {}, {}]

使用mapfilter等数组方法

// 使用map方法
var set = new Set([1, 2, 3])
set = new Set([...set].map(s => s * 2))
for (let s of set) {
    console.log(s) // 2, 4, 6
}

// 使用filter方法
var set = new Set([1, 2, 3])
set = new Set([...set].filter(s => s > 1))
for (let s of set) {
    consle.log(s) // 2, 3
}

实现数据之间的并集、交集和差集

var set1 = new Set([1, 2, 3])
var set2 = new Set([1, 3, 5, 7])

// 并集
var union = new Set([...set1, ...set2])
for (var item of union) {
    console.log(item) // 1, 2, 3, 5, 7
}

// 交集
var intersect = new Set([...set1].filter(item => set2.has(item)))
for (var item of intersect) {
    console.log(item) // 1, 3
}

// 差集
var difference = new Set([...set1].filter(item => !set2.has(item)))
for (var item of difference) {
    console.log(item) // 2
}

遍历修改数据源

利用...拓展运算符和map方法

var set = new Set([1, 2, 3])
set = new Set([...set].map(s => s * 2))
for(let s of set) {
    console.log(s)
}

利用Array.from的第二个参数,进行数据处理

var set = new Set([1, 2, 3])
set = new Set(Array.from(set, val => val * 2))
for(let s of set) {
    console.log(s)
}

Map数据结构

ES6提供了Map数据结构,类似于对象,也是键值对的集合,但是键的范围不限于字符串,各种类型的值都可以当做键,解决了传统对象Object只能使用字符串作为键名的缺陷

// 创建对象的时候进行初始化操作
var map = new Map([['name', 'xxx'], ['age', 22]])
console.log(map.get('name')) // 'xxx'
console.log(map.get('age'))  // 22

// 使用set方法添加数据
var map = new Map()
map.set('name', 'xxx')
map.set('age', 22)
console.log(map.get('name')) // 'xxx'
console.log(map.get('age'))  // 22

Map结构赋值的一些注意点

  • 判断属性名是否存在,使用和Set数据结构一样的同值相等判断法
var k1 = ['a']
var k2 = ['a']

var map = new Map([
    [true, '123'],
    ['true', '123'],
    [k1, 'foo'],
    [k2, 'bar'],
])
console.log(map.get(true)) // 123
console.log(map.get('true')) // 123

console.log(map.get(k1)) // 'foo'
console.log(map.get(k2)) // 'bar'
  • 对同一个键值进行对此赋值,后面的值将覆盖前面的值
var map = new Map([
    [true, '123'],
    ['true', '123']
])
console.log(map.get(true)) // 123

map.set(true, '456')
console.log(map.get(true)) // 456
  • 获取一个未知的键名,会返回undefined
var map = new Map([
    [true, '123'],
    ['true', '123']
])

console.log(map.get(false)) // undefined

Map的实例属性和操作方法

  • size属性,用来获取map实例的长度
  • set(key, value)方法,设置key对应的键值,如果键名存在,就更新键值;如果键名不存在,就新生成改键
  • get(key)方法,返回键名对应的键值,没有返回undefined
  • has(key)方法,返回一个boolean值,表示map对象中是否包含某个键名
  • delete(key)方法,返回一个boolean值,删除成功,返回true;删除失败,返回false
  • clear()方法,清空map对象
var map = new Map([
    ['name', 'xxx'],
    ['age', 12]
])
console.log(map.size) // 2

map.set('sex', 'male')
console.log(map.get('sex')) // male

map.set('age', 24)
console.log(map.get('age')) // 24

console.log(map.has('name')) // true
console.log(map.has('weight')) // false

console.log(map.delete('name')) // true
console.log(map.get(name)) // undefined

map.clear()
console.log(map.size) // 0

Map结构的遍历操作

Map数据结构的遍历操作基本与Set一致,但是Set[Symbol.iterator] === Set.prototype.entries

Map结构与其他数据结构的转换

  • Map与数组之间的相互转换(数组必须是二维数组)
// map => arr
var map = new Map([
    ['name', 'xxx'],
    [age, 24],
])
console.log([...map]) // [['name', 'xxx'], ['age', 24]]

// arr => map
var arr = [[true, 7], [{foo: 3}, ['abc']]]
var map = new Map(arr)
for(let m of map) {
    console.log(m) // [true, 7] [{foo: 3}, ['abc']]
}
  • Map与对象之间的相互转换
// map => obj
// Map的键都是字符串,它可以转为对象
function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToObj(myMap) // { yes: true, no: false }

// obj => map
function objToStrMap(obj) {
  let strMap = new Map();
  for (let k of Object.keys(obj)) {
    strMap.set(k, obj[k]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false}) // [ [ 'yes', true ], [ 'no', false ] ]

Set和Map的区别

  • 都是用来存储数据用的,但是存储的数据格式不同
  • Set直接存储任意类型数据,Map存储数据的时候,必须以key:value的形式
  • Set使用forEach遍历的时候,keyvalue值是一样的; 而map遍历的时候,key就是存进去的对象的key,value就是存在的值
  • for...of进行遍历的时候,Set[Symbol.iterator]方法是原型链上的values方法,而Map[Symbol.iterator]方法是原型链上的entries方法
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值