认识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))
相关推荐
奈斯先生Vector5 分钟前
大模型 Agentic Workflow 架构解构:异构 API 调度与 Token 路由的多模态系统设计
开发语言·前端·架构·prompt·aigc·音视频
海带紫菜菠萝汤7 分钟前
FFmpeg.wasm 实践:在浏览器中运行 FFmpeg 的能力边界与性能瓶颈
前端·javascript·ffmpeg·音视频·wasm
冻柠檬飞冰走茶9 分钟前
PTA基础编程题目集 7-20 打印九九口诀表(C语言实现)
c语言·开发语言·数据结构·算法
鱼子星_10 分钟前
《算 · 法》题目解析篇(1):最近公共祖先问题,线段树,最长回文子序列
c++·算法·动态规划·递归
雾喔12 分钟前
算法练习5
算法·代理模式
名字还没想好☜15 分钟前
React 受控输入框光标跳到末尾:格式化输入时的 selection 丢失 bug 与修复
前端·javascript·react.js·bug·react·next.js
Access开发易登软件15 分钟前
Access 怎么做前后端分离?用 Web API 读写 SQL Server
前端·数据库·人工智能·microsoft·excel·access
10share24 分钟前
React 新一代样式隔离方案 —— 编译时、零运行时、原生写法
前端·react.js
问商十三载26 分钟前
RAG 检索召回越多越好?2026 信噪比模型深度解析
人工智能·算法·机器学习
额恩6627 分钟前
ResearchPilot 第三阶段总结报告
python·算法