认识Set和Map(常用完整版)

作为ES6新增的数据结构,在平时的业务中我倒是没怎么使用过,但是在刷算法题中,Set和Map倒是经常登场。Set作为哈希表,Map作为对象plus,下面就来一起学习一下Set和Map的使用吧

实例属性

Set.prototype.size ,和数组的长度一样理解就行,不过是length换成了size

实例方法

Set.prototype.add() ,如果Set中没有该元素,则插入,且每次只能插入一个元素。注意,Set中每个元素只能插入一次,既同一个Set集合中不能存在相同的元素

Set.prototype.clear() : 清除Set集合中所有的元素

Set.prototype.delete() : 移除某个元素,并返回一个布尔值表示是否移除成功

Set.prototype.entries()

返回一个新的迭代器对象,该对象包含 Set 对象中的代表每个元素的 [value, value] 数组 。这与 Map 对象类似,因此 Set 的每个条目的 keyvalue 都相同。

Set.prototype.forEach()

按照值插入的顺序为 Set 对象中的每个值调用一次 callbackFn。如果提供了 thisArg 参数,它将被用作每次调用 callbackFn 时的 this 值。

Set.prototype.has() :返回一个布尔值,表示Set中是否存在该元素

Set.prototype.keys()和Set.protrtypr.values()返回是一个东西,即键值相同

除了forEach,for...of..也可以迭代

javascript 复制代码
const mySet = new Set(['a','b','c','d'])
for (const [key,value] of mySet.entries()) {
    console.log(`The key ${key} and the value ${value} is the same!`)
}
// The key a and the value a is the same!
// The key b and the value b is the same!
// The key c and the value c is the same!
// The key d and the value d is the same!

Set和Array的相互转换

csharp 复制代码
let set = new Set([1,2,3,4])   //数组转Set 
console.log(set)				//{1,2,3,4}
let arr = [...set]              //Set转数组法2
let arr2 = Array.from(set)      //Set转数组法1
console.log(arr)				//[1,2,3,4]
console.log(arr2)				//[1,2,3,4]
javascript 复制代码
let set = new Set([1,2,3,4])  
// 求数组[2,3,4]和Set{1,2,3,4}的交集
const intersection = new Set([2,3,4].filter((item)=>set.has(item)))
console.log(intersection)        //{2,3,4}
// 求数组[4,5,6]和Set{1,2,3,4}的差集
const difference = new Set([4,5,6].filter((item)=>!set.has(item)))
console.log(difference)         //{5,6}

数组去重

ini 复制代码
// 用于从数组中删除重复元素

const numbers = [2, 3, 4, 4, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 5, 32, 3, 4, 5];

console.log([...new Set(numbers)]);

// [2, 3, 4, 5, 6, 7, 32]

Set与字符串的关系

sql 复制代码
const mySet = new Set('India')
console.log(mySet.size)       //5
// 大小写敏感,且忽略重复项
new Set("Firefox"); // Set(7) { "F", "i", "r", "e", "f", "o", "x" }
new Set("firefox"); // Set(6) { "f", "i", "r", "e", "o", "x" }

这里附上MDN参考网站Set - JavaScript | MDN (mozilla.org)

javascript 复制代码
let obj ={
    'a':1,
    'b':2,
     c:3      //Object的键只能是字符或Symbol,它会自己转
}
const keys= Object.keys(obj)
console.log(keys)
const values= Object.values(obj)
console.log(values)
const arrs = Object.entries(obj)
console.table(arrs)

Map有个神奇的地方就是它可以复制,给我的感觉是和Object.assign一样,而且两者都是浅复制(拷贝),而Set是没有类似方法的

ini 复制代码
const obj= {
    a:0,
    b:{c:1}
}
const target = {}
const obj2 = Object.assign(target,obj)
obj2.b.c = 0		//因为是浅拷贝,对.b的值同一个引用,所以obj.b.c也会变
console.log(obj2)    //{a:0,b:{c:0}}  
console.log(obj)    //{a:0,b:{c:0}}  
console.log(target===obj2)  //true

这里提供一个深拷贝的方法

ini 复制代码
const obj3 = { a: 0, b: { c: 0 } };
const obj4 = JSON.parse(JSON.stringify(obj3));
obj3.a = 4;
obj3.b.c = 4;
console.log(obj4); // { a: 0, b: { c: 0 } }
javascript 复制代码
const myMap= new Map([['a','字母']])
console.log(myMap)
const myMap2 = new Map(myMap)
console.log(myMap2)
console.log(myMap===myMap2)		//false

实例属性

这些属性在 Map.prototype 上定义,并由所有 Map 实例共享。

Map.prototype.size

返回 Map 对象中的键值对数量。

实例方法

Map.prototype.clear()

移除 Map 对象中所有的键值对。

Map.prototype.delete()

移除 Map 对象中指定的键值对,如果键值对存在并成功被移除,返回 true,否则返回 false。调用 delete 后再调用 map.has(key) 将返回 false

Map.prototype.forEach()

以插入顺序为 Map 对象中的每个键值对调用一次 callbackFn。如果为 forEach 提供了 thisArg 参数,则它将作为每一次 callback 的 this 值。

Map.prototype.set()

Map 对象中设置与指定的键 key 关联的值,并返回 Map 对象。

Map.prototype.get()

返回与指定的键 key 关联的值,若不存在关联的值,则返回 undefined

Map.prototype.has()

返回一个布尔值,用来表明 Map 对象中是否存在与指定的键 key 关联的值。

Map.prototype.keys()

返回一个新的迭代器对象,其包含 Map 对象中所有元素的键,以插入顺序排列。

Map.prototype.values()

返回一个新的迭代对象,其中包含 Map 对象中所有的值,并以插入 Map 对象的顺序排列。

Map.prototype.entries()

返回一个新的迭代器对象,其包含 Map 对象中所有键值对 [key, value] 二元数组,以插入顺序排列。

使用 for...of 迭代 Map

Map 可以使用 for...of 循环来实现迭代:

javascript 复制代码
const myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");

for (const [key, value] of myMap) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

for (const key of myMap.keys()) {
  console.log(key);
}
// 0
// 1

for (const value of myMap.values()) {
  console.log(value);
}
// zero
// one

for (const [key, value] of myMap.entries()) {
  console.log(`${key} = ${value}`);
}
// 0 = zero
// 1 = one

使用 forEach() 迭代 Map

Map 也可以通过 forEach() 方法迭代:

javascript 复制代码
myMap.forEach((value, key) => {
  console.log(`${key} = ${value}`);
});
// 0 = zero
// 1 = one

这里附赠个数组去重的的

数组里全是原始类型,直接用Set,但如果是引用类型那Set就失效了,这里看了某博主分享的后,自己也手写了一遍,注释比较全,嘿嘿!

javascript 复制代码
        function uniqueArr(arr) {
            const res = []
            for (let iterator of arr) {
                let sameFlag = false
                for (let item of res) {
                    if (equl(iterator, item)) {     //有相等就退出
                        sameFlag = true
                        break
                    }
                }
                if (!sameFlag) res.push(iterator)
            }
            return res
        }
        function equl(obj1, obj2) {
            if ((typeof obj1 === 'object' && obj1 !== null) && (typeof obj2 === 'object' && obj2 !== null)) {
                // 都是非null的对象
                if (Object.keys(obj1).length !== Object.keys(obj2).length) return false
                for (const key in obj1) {
                    if (obj2.hasOwnProperty(key)) {
                        if (!equl(obj1[key], obj2[key])) {
                            // 属性值不相同,返回false
                            return false;
                        }
                    } else {
                        // 没有相同的key,直接返回false
                        return false;
                    }
                }
                // 能到这,就是属性数量、属性名、属性值都相同,那就可以判定这两个对象相同
                return true;
            } else {
                // 原始类型作比较,最后的出口
                return obj1 === obj2
            }
        }
        let arr = [1, 1, '2', 3, 1, 2,
            { name: '张三', id: { n: 1 } },
            { name: '张三', id: { n: 1 } },
            { name: '张三', id: { n: 2 } }
        ]
        console.log(uniqueArr(arr))
相关推荐
广州华水科技13 分钟前
单北斗GNSS在桥梁形变监测中的应用与技术进展分析
前端
我讲个笑话你可别哭啊14 分钟前
鸿蒙ArkTS快速入门
前端·ts·arkts·鸿蒙·方舟开发框架
CherryLee_121016 分钟前
基于poplar-annotation前端插件封装文本标注组件及使用
前端·文本标注
特立独行的猫a23 分钟前
C++轻量级Web框架介绍与对比:Crow与httplib
开发语言·前端·c++·crow·httplib
周航宇JoeZhou25 分钟前
JB2-7-HTML
java·前端·容器·html·h5·标签·表单
代码小库27 分钟前
【课程作业必备】Web开发技术HTML静态网站模板 - 校园动漫社团主题完整源码
前端·html
Not Dr.Wang42227 分钟前
自动控制系统稳定性研究及判据分析
算法
VT.馒头27 分钟前
【力扣】2722. 根据 ID 合并两个数组
javascript·算法·leetcode·职场和发展·typescript
ffqws_33 分钟前
A*算法:P5507 机关 题解
算法
珹洺34 分钟前
Bootstrap-HTML(二)深入探索容器,网格系统和排版
前端·css·bootstrap·html·dubbo