认识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))
相关推荐
天选之女wow4 分钟前
【代码随想录算法训练营——Day32】动态规划——509.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯
算法·leetcode·动态规划
红衣小蛇妖11 分钟前
LeetCode-704-二分查找
java·算法·leetcode·职场和发展
rongqing201916 分钟前
问题记录:一个简单的字符串正则匹配算法引发的 CPU 告警
算法
树叶会结冰18 分钟前
HTML语义化:当网页会说话
前端·html
冰万森23 分钟前
解决 React 项目初始化(npx create-react-app)速度慢的 7 个实用方案
前端·react.js·前端框架
无限进步_32 分钟前
C语言字符串与内存操作函数完全指南
c语言·c++·算法
牧羊人_myr36 分钟前
Ajax 技术详解
前端
rengang6640 分钟前
07-逻辑回归:分析用于分类问题的逻辑回归模型及其数学原理
人工智能·算法·机器学习·分类·逻辑回归
浩男孩1 小时前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端