Set对象,类似数组
Set类型数组,但是成员的值都是唯一的,Set内的元素是强类型,会进行类型检查。Set是一种叫做集合的数据结构
- 集合是由一组无序且唯一(即不能重复)的项组成的,可以想象成集合是一个既没有重复元素,也没有顺序概念的数组
- ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值
-
Set实例的属性和方法
Set的属性
-
Set的方法
操作方法
- add(value):向集合添加一个新的项
- delete(value):从集合中移除一个值
- has(value):如果值在集合中存在,返回true,否则false
- clear(): 移除集合里所有的项
遍历方法
- keys():返回一个包含集合中所有键的数组
- values():返回一个包含集合中所有值的数组
- entries:返回一个包含集合中所有键值对的数组
- forEach():用于对集合所有成员执行某种操作,没有返回值
// 创建Set,提供一个Array作为输入,或者直接创建空Set
let 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和value
this.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值重新赋值给values
for(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和value
this.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值重新赋值给values
for(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():
// 创建Map
const 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,如果有,直接返回对应的值
// 如果么有,返回undefined
return 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的完整实现代码
```javascript
function 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 获取的value
for (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,然后在转为JSON
return 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 里面的键名对象和所对应的键值对会自动消失,不用手动删除引用。