认识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))
相关推荐
有梦想的刺儿19 分钟前
webWorker基本用法
前端·javascript·vue.js
sp_fyf_202432 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-01
人工智能·深度学习·神经网络·算法·机器学习·语言模型·数据挖掘
cy玩具40 分钟前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
香菜大丸1 小时前
链表的归并排序
数据结构·算法·链表
jrrz08281 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
oliveira-time1 小时前
golang学习2
算法
qq_390161771 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test2 小时前
js下载excel示例demo
前端·javascript·excel
南宫生2 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
Yaml42 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理