ES6中Set和Map数据结构的基本概念及应用
2017-11-24 11:15
836 查看
1. Set数据结构介绍的特点
ES6中提供了新的数据结构Set和Map。Set类似于Array,但内部存储的数据不允许重复。该方法可接受具有Iterable接口的其他数据结构作为参数。例如:
let set=new Set([1,2,3,3]); console.log(set); // Set(3) {1, 2, 3}
由此我们生成了一个Set结构的数据。但需要注意,虽然NaN===NaN不成立,但Set存储数据时’认为’NaN等于自己,于是Set结构只会存储一个NaN。
let set=new Set([NaN,NaN]); console.log(set); // Set(1) {NaN}
但{}==={}返回false在Set中会正常应用,即
let set=new Set([{},{}]); console.log(set); // Set(2) {{…}, {…}}
将Set转为Array方法有2种:
(1)Set结构的数据同样可以使用可接受Iterable的扩展运算符’…’
let set=new Set([1,2,3,3]); [...set] // [1,2,3]
显而易见,我们可以用此方法轻松去重。
(2)Array.from()方法可将具有Iterable或ArrayLike的数据类型转为Array结构的数据
Array.from(new Set([1,2,3])) // [1,2,3]
2. Set数据结构的属性和方法
2.1 属性 Set.prototype.constructor作用:构造函数,默认就是Set函数
2.2 属性 Set.prototype.size
作用:返回Set大小
let set=new Set([1,2,3,3]); set.size // 3
2.3 方法Set.prototype.add(value)
作用:向Set数据结构中添加数据,可链式添加。
let set=new Set([1,2,3,3]); set.add(4).add('a') // Set(5) {1,2,3,4,'a'}
2.4 方法Set.prototype.has(value)
作用:返回一个布尔值,表示该值是否为Set的成员
let set=new Set([1,2,3,3]); set.has(2) // true
2.5 方法Set.prototype.delete(value)
作用:删除某个值,返回一个布尔值,表示删除是否成功
let set=new Set([1,2,3,3]); set.delete(2) // true set // Set(2) {1,3}
2.6 方法Set.prototype.clear()
作用:清除所有set中保存的数据
3. Set的遍历操作
set实例具有四个遍历的方法:keys(),values(),entries(),forEach()。3.1 keys(),values(),entries()
keys()将set实例的所有键名作为SetIterator返回,values()将set实例的所有键值作为SetIterable返回。entries()同样返回SetIterable,在console.log时会将该实例此时的键名与键值打印出来。keys(),values(),entries()方法返回的SetIterable本质上是不同的,从打印结果就可以看出。由于Set结构数据类似于Array数据,key与value相同,因此keys()与values()返回的值完全相同,entries()返回的每个表示键值对的数组中的2个元素的数值同样相同。
let set=new Set([1,2,3,3]); for(let i of set.keys()){ console.log(i); } //1 //2 //3 set.keys() // SetIterator {1, 2, 3} for (let i of set.entries()) { console.log(i); } // ['1':'1'] // ['2':'2'] // ['3':'3'] set.entries() // SetIterator {1, 2, 3}
由于set实例的默认遍历器生成函数是它的values()方法
Set.prototype[Symbol.iterator] === Set.prototype.values // true
也就是说Set数据结构具有一个默认的iterator接口(该接口由它的values()方法生成的),因此可以对set实例直接进行for/of遍历,此处不再举例说明。
3.2 forEach()
类似于Array,Set结构也拥有forEach()方法,不过callback的参数与Array的不同。Array.prototype.forEach(callback(currentValue,index,array){}[,thisArg]),Set.prototype.forEach(callback(value,key){}[,thisArg]),当然了每次执行时的value与key是相同的。forEach()返回undefined,另外不会改变对象里的值。关于map、forEach的区别可以参考以下回答。
同样的,Array的map与filter方法也可用于Set类型数据。不过得先转成数组形式,可以参考1中的’将Set转为Array2种方法’,注意map和filter有返回值。
4. WeakSet
WeakSet与Set类型基本一致,值得注意的是WeakSet里边存放成员的只能是对象类型,例如let weakset=new WeakSet(); weakset.add({}); // 正确 weakset.add([]); //正确 weakset.add(1); // 错误
另外WeakSet的成员对象都采用弱引用,垃圾回收机制可以回收WeakSet引用的对象所占用的内存。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。所以WeakSet的成员不适合引用,可能会被随时清理掉。另外也不可遍历,因此也没有size属性和forEach操作。
WeakSet具有add(),deldete(),has()方法,用法与Set一致,不过传的参数都是对象类型。
5. Map数据类型
Map类型的出现是为了解决传统JavaScript对象中的键值对的键名只能是字符串,由此会带来一些不便。而Map数据类型类似于对象,也是键值对的集合,但键名可以是任何类型数据,包括Number,Object,Boolean等。用法:
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赋值时,若键名是Number,NaN(set时会认为NaN等于它本身)或Boolean,在多次赋同样键名的值会有替换效果。例如:
const map = new Map(); map .set(1, 'aaa') .set(1, 'bbb'); map.get(1) // "bbb"
若键名是字符串,则不会有此问题,因为字符串作键名会和内存地址绑定,同一字符的不同实例的内存地址不同。
const map = new Map(); const k1 = ['a']; const k2 = ['a']; map .set(k1, 111) .set(k2, 222); map.get(k1) // 111 map.get(k2) // 222
但链式set由于指向统一内存地址,因此会有值替换效果。
const map = new Map(); map .set('a', 'aaa') .set('a', 'bbb'); map.get('a') // 'bbb'
Map数据结构同样有size属性,set(key,value),get(key),has(key),delete(key),clear()方法。
可以通过它的keys(),values(),entries(),或实例(等同于entries)提供的Iterable接口用for/of遍历,
const map = new Map([ ['F', 'no'], ['T', 'yes'], ]); for (let key of map.keys()) { console.log(key); } // "F" // "T" for (let item of map.entries()) { console.log(item[0], item[1]); } // "F" "no" // "T" "yes" for (let [key, value] of map) { console.log(key, value); } // "F" "no" // "T" "yes" for (let item of map) { console.log(item); } // ["F", "no"] // ["T", "yes"]
也可以对实例直接forEach遍历。
map.forEach(function(value, key, map) { console.log("Key: %s, Value: %s", key, value); }) // Key: F, Value: no // Key: T, Value: yes
——参考阮一峰《ES6入门》
相关文章推荐
- Java基本概念:集合类 List/Set/Map... 的区别和联系
- Java基本概念:集合类 List/Set/Map... 的区别和联系
- 【转】Java基本概念:集合类 List/Set/Map...的区别
- map与set的基本应用
- 数据结构的基本概念 单链表的应用
- ES6---for...of遍历‘类似’数组的数据结构,array set map string与iterator
- ES6新特性五:Set与Map的数据结构实例分析
- ES6---新增数据结构set、map
- Java中list.map.set基本概念,方法比较和遍历方式
- java基本概念:list set map区别和联系
- Java基本概念:集合类(Collection)List/Set/Map... 的区别和联系
- ES6---扩展运算符和rest‘...’(三点运算符),在数组、函数、set/map等中的应用
- Java基本概念:集合类 List/Set/Map... 的区别和联系
- ES6---扩展运算符和rest‘...’(三点运算符),在数组、函数、set/map等中的应用
- Java基本概念:集合类 List/Set/Map... 的区别和联系
- Java基本概念:集合类(Collection)List/Set/Map的区别和联系
- map,list,set的数据结构和应用
- Java基本概念:集合类 List/Set/Map... 的区别和联系
- 数据结构 学习笔记(一):基本概念:什么是数据结构和算法,应用实例
- Java基本概念:集合类 List/Set/Map... 的区别和联系