Set对象,类似数组
Set类型数组,但是成员的值都是唯一的,Set内的元素是强类型,会进行类型检查。Set是一种叫做集合的数据结构
- 集合是由一组无序且唯一(即不能重复)的项组成的,可以想象成集合是一个既没有重复元素,也没有顺序概念的数组
- ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
-
Set实例的属性和方法
Set的属性
-
Set的方法
操作方法
- add(value):向集合添加一个新的项
- delete(value):从集合中移除一个值
- has(value):如果值在集合中存在,返回true,否则false
- clear(): 移除集合里所有的项
遍历方法
- keys():返回一个包含集合中所有键的数组
- values():返回一个包含集合中所有值的数组
- entries:返回一个包含集合中所有键值对的数组
- forEach():用于对集合所有成员执行某种操作,没有返回值
// 创建Set,提供一个Array作为输入,或者直接创建空Setlet s = new Set();let s1 = new Set([1,2,"1","a",2,8])console.log(s1) // Set(5) {1, 2, "1", "a", 8}
Set方法的原理实现
创建一个Set对象function Set(arr = []){let items = {};this.size = 0;}module.exports = Set;
has方法
首先实现has方法,该方法会在后边几个方法中被使用到 ```javascript function Set(arr = []){ let items = {}; this.size = 0;
this.has = function(val){ //判断对象是否拥有特定属性,使用hasOwnProperty方法 return items.hasOwnProperty(val) } } module.exports = Set; ```
add方法
对于给定的val,检测是否存在于集合中
如果不存在,就添加到集合
如果存在,返回false,不做任何操作
this.add = function(val){if(!this.has(val)){items[val] = val;this.size++;return true;}return false;}
delete和clear方法
delete方法先判断val是否存在Set中,如果存在直接从Set中删除,返回true
// delete方法this.delete = function(val){if(this.has(val)){delete items[val];this.size--;return true;}return false;}// clear方法this.clear = function(){items = {};this.size = 0;}
keys和values方法
//遍历key和valuethis.keys = function(){return Object.keys(items);}this.values = function(){return Object.values(items);}
union并集
//union并集this.union = function(other){let union = new Set()let values = this.values;for(let i=0;i<values.length;i++){union.add(values[i])}values = other.values(); // 将另一个set的value值重新赋值给valuesfor(let j=0;j<values.length;j++){union.add(values[i])}return union;}
intersect交集
this.intersect = function(other){let intersect = new Set();let values =this.values;for(let i=0;i<values.length;i++){if(other.has(values[i])){intersect.add(values[i])}}return intersect;}
difference差集
差集的意思是:集合A和集合B的差集,表示A-B集合;前面集合减去后边集合的元素
this.difference = function(other){let difference = new Set()let values = this.values()for(let i=0; i<values.length;i++){if(!other.has(value[i])){difference.add(values[i])}}return difference;}
Set的完整代码
function Set(arr = []){let items = {};this.size = 0;//has方法this.has = function(val){//判断对象是否拥有特定属性,使用hasOwnProperty方法return items.hasOwnProperty(val)}// add方法this.add = function(val){if(!this.has(val)){items[val] = val;this.size++;return true;}return false;}arr.forEach((val,i)=>{this.add(val);})// delete方法this.delete = function(val){if(this.has(val)){delete items[val];this.size--;return true;}return false;}// clear方法this.clear = function(){items = {};this.size = 0;}//遍历key和valuethis.keys = function(){return Object.keys(items);}this.values = function(){return Object.values(items);}//union并集this.union = function(other){let union = new Set()let values = this.values;for(let i=0;i<values.length;i++){union.add(values[i])}values = other.values(); // 将另一个set的value值重新赋值给valuesfor(let j=0;j<values.length;j++){union.add(values[i])}return union;}// 交集this.intersect = function(other){let intersect = new Set();let values =this.values;for(let i=0;i<values.length;i++){if(other.has(values[i])){intersect.add(values[i])}}return intersect;}// 差集this.difference = function(other){let difference = new Set()let values = this.values()for(let i=0; i<values.length;i++){if(!other.has(value[i])){difference.add(values[i])}}return difference;}}module.exports = Set;
测试
const Set = require("./set.js");let set = new Set();set.add(1);set.add(2);set.add(3);console.log(set.size, set.keys());set.delete(2)console.log(set.values());set.clear();
使用Set处理并集(Union)、交集(Intersect)、差集(Difference)
let a = new Set([1,2,3])let b = new set([2,3,4])
并集Union
let union = new Set([...a, ...b]);console.log(union) // Set{1,2,3,4}
交集Intersect
let intersect = new Set([...a].filter(x=> b.has(x)))console.log(intersect) // Set {2,3}
差集difference
// a相对b的差集let defference = new Set([...a].filter(x => !b.has(x)))console.log(defference) // Set {1}
Map对象
Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。键值对结构
- 极快速查找
Set和Map的区别:
- 共同点:
-
Map对象的属性和方法
属性:
-
操作方法
set(key,val)
- get(key)
- has(key)
- delete(key)
-
遍历方法
keys():
- values():
- forEach():
// 创建Mapconst map = new Map([['name', 'sammy'],['title', 'author']])map.size //2 size 是属性,不是函数map.has('name')map.get('name')
Map方法的原理实现
创建一个Map对象function Map(){let items = {}}modules.exports = Map;
has方法
function Map(){let items = {};this.has = function(){return items.hasOwnProperty(val)}}
set和get方法
// set(key, val)// set相同key,后面声明的会覆盖前面的值this.set = function(key, val){item[key] = val;}// get(key)this.get = function(key){// 判断是否有key,如果有,直接返回对应的值// 如果么有,返回undefinedreturn this.has(key) ? items[key] : undefined;}
delete和clear方法
this.delete = function(key){if(this.has(key)){delete items[key];this.size--;return true}return false;}this.clear = function(){items = {};this.size = 0;}
遍历方法keys/values/forEach
```javascript this.keys = function(){ return Object.keys(items) }
this.values = function(){ return Object.values(items) }
this.forEach= function(fn, context=this){ for(let i=0;i<this.size;i++){ let key = Object.keys(items)[i]; let value = Object.values(items)[i]; fn.call(context, value, key, items); } }
<a name="Mzpa4"></a>### Map的完整实现代码```javascriptfunction Map() {let items = {};this.size = 0;// 操作方法// has方法this.has = function(val) {return items.hasOwnProperty(val);};// set(key, val)方法this.set = function(key, val) {items[key] = val;this.size++;};// get(key)方法this.get = function(key) {return this.has(key) ? items[key] : undefined;};// delete(key)方法this.delete = function(key) {if (this.has(key)) {delete items[key];this.size--;return true;}return false;};// clear()方法this.clear = function() {items = {};this.size = 0;};// 遍历方法// keys()方法this.keys = function() {return Object.keys(items);};// values()方法this.values = function() {return Object.values(items);};// forEach(fn, context)方法this.forEach = function(fn, context = this) {for (let i = 0; i < this.size; i++) {let key = Object.keys(items)[i];let value = Object.values(items)[i];fn.call(context, value, key, items);}};}module.exports = Map;
测试
const Map = require('./Map.js')let m = new Map();m.set("name","map object")let o = new Object()m.set(o, "object");console.log(m.size, m.keys(), m.values(), m.get(o))m.delete("name")
Map to Array
let map1 = new Map().set(true, 8).set({foo:3}, ['aaa'])console.log([...map1]) // [[true,7], [{foo:3}, ['aaa']]]
Array to Map
let arr = [[true,7], [{foo:3}, ['abc']]]let map2 = new Map(arr)console.log(map2)// Map{// true => 7,// Object {foo:3} => ['aaa']// }
Map to Object
function strMapToObj(strMap) {let obj = Object.create(null);// for in 获取的key// for of 获取的valuefor (let [k,v] of strMap) {obj[k] = v;}return obj;}const map3= new Map().set("yes",true).set("no", false)strMapToObj(map3) // { yes: true, no: false }
Object To Map
function objToStrMap(obj){return new Map(Object.entries(obj))}let obj = {"a":1, "b":2}console.log(objToStrmap(obj))
Map to JSON
function strMapToJson(strMap) {// 先将Map转为Object,然后在转为JSONreturn JSON.stringify(strMapToObj(strMap));}let myMap = new Map().set('yes', true).set('no', false);strMapToJson(myMap)// '{"yes":true,"no":false}'
JSON to Map
function jsonToStrMap(jsonStr) {return objToStrMap(JSON.parse(jsonStr));}jsonToStrMap('{"yes": true, "no": false}')// Map {'yes' => true, 'no' => false}
WeakSet和WeakMap对象
WeakSet && WeakMap 所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内。因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放该对象所占用的内存。也就是说,一旦不再需要,WeakSet && WeakMap 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。
