Map,Set

Map

Map 对象保存键值对,并且能够记住键的原始插入顺序任何值(对象或者基本类型)都可以作为一个键或一个值

//创建Map只能通过new
const myMap = new Map([
    [1, 'one'],
    [2, 'two'],
    [3, 'three'],
]);
const map1 = new Map();

map1.set('a', 1);
map1.set('b', 2);
map1.set('c', 3);
console.log(typeof map1)//object

for (const map1Element of map1) {
    console.log(map1Element)
}
//[ 'a', 1 ]
//[ 'b', 2 ]
//[ 'c', 3 ]

使用对象的设置属性方法

map1.name = 'tom'
console.log(map1)//Map(3) { 'a' => 1, 'b' => 2, 'c' => 3, name: 'tom' }
console.log(map1.has('name'))//false   
//name并未真正存到map1中,迭代或查询也找不到
for (const map1Element of map1) {
    console.log(map1Element)
}
//[ 'a', 1 ]
//[ 'b', 2 ]
//[ 'c', 3 ]

在Map上存储应该用set(key, value)方法

Map和Object对比

MapObject
意外的键Map 默认情况不包含任何键。只包含显式插入的键。一个 Object 有一个原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。**备注:**虽然可以用 Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。
键的类型一个 Map 的键可以是任意值,包括函数、对象或任意基本类型。一个 Object 的键必须是一个 String 或是 Symbol
键的顺序Map 中的键是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。虽然 Object 的键目前是有序的,但并不总是这样,而且这个顺序是复杂的。因此,最好不要依赖属性的顺序。自 ECMAScript 2015 规范以来,对象的属性被定义为是有序的;ECMAScript 2020 则额外定义了继承属性的顺序。参见 OrdinaryOwnPropertyKeysEnumerateObjectProperties 抽象规范说明。但是,请注意没有可以迭代对象所有属性的机制,每一种机制只包含了属性的不同子集。(for-in 仅包含了以字符串为键的属性;Object.keys 仅包含了对象自身的、可枚举的、以字符串为键的属性;Object.getOwnPropertyNames 包含了所有以字符串为键的属性,即使是不可枚举的;Object.getOwnPropertySymbols 与前者类似,但其包含的是以 Symbol 为键的属性,等等。)
SizeMap 的键值对个数可以轻易地通过 size 属性获取。Object 的键值对个数只能手动计算。
迭代Map可迭代的 的,所以可以直接被迭代。**Object 没有实现 迭代协议,所以使用 JavaSctipt 的 for…of 表达式并不能直接迭代对象。**备注:对象可以实现迭代协议,或者你可以使用 Object.keysObject.entriesfor…in 表达式允许你迭代一个对象的可枚举属性。
性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。
序列化和解析没有元素的序列化和解析的支持。(但是你可以使用携带 replacer 参数的 JSON.stringify() 创建一个自己的对 Map 的序列化和解析支持。参见 Stack Overflow 上的提问:How do you JSON.stringify an ES6 Map?原生的由 Object 到 JSON 的序列化支持,使用 JSON.stringify()。原生的由 JSON 到 Object 的解析支持,使用 JSON.parse()

Set

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。Set 中的元素只会出现一次,即 Set 中的元素是唯一的

//创建Set只能通过new
const mySet = new Set(['hello',1,2,true,function a(){console.a('hi!~')}])
console.log(typeof myset)//object
console.log(mySet)//Set(5) { 'hello', 1, 2, true, [Function: a] }
mySet.add("some text"); // Set [ 1, 5, "some text" ]
//迭代Set
for (const item of mySet) {
    console.log(item)
}
//hello
//1
//2
//true
//[Function: a]
//some text
// 判断两个集合是否相等
function isSuperset(set, subset) {
    for (let elem of subset) {
        if (!set.has(elem)) {
            return false;
        }
    }
    return true;
}
// Set 和 Array 互换
mySet2 = new Set([1, 2, 3, 4]);
mySet2.size;               // 4
[...mySet2];               // [1,2,3,4]
//合并两个Set
function union(setA, setB) {
    let _union = new Set(setA);
    for (let elem of setB) {
        _union.add(elem);
    }
    return _union;
}
let set1 = new Set([1,2,3,4])
let set2 = new Set([5,6,7,8])
console.log(union(set1, set2))//Set(8) { 1, 2, 3, 4, 5, 6, 7, 8 }
// 找两个Set的交集
function intersection(setA, setB) {
    let _intersection = new Set();
    for (let elem of setB) {
        if (setA.has(elem)) {
            _intersection.add(elem);
        }
    }
    return _intersection;
}
let set1 = new Set([1,2,3,4])
let set2 = new Set([3,4,5,6])
console.log(intersection(set1, set2))//Set(2) { 3, 4 }
//找两个Set的差集
function symmetricDifference(setA, setB) {
    let _difference = new Set(setA);
    for (let elem of setB) {
        if (_difference.has(elem)) {
            _difference.delete(elem);
        } else {
            _difference.add(elem);
        }
    }
    return _difference;
}
let set1 = new Set([1,2,3,4])
let set2 = new Set([3,4,5,6])
console.log(symmetricDifference(set1, set2))//Set(4) { 1, 2, 5, 6 }
//删除A中和B一样的元素
function difference(setA, setB) {
    let _difference = new Set(setA);
    for (let elem of setB) {
        _difference.delete(elem);
    }
    return _difference;
}
let set1 = new Set([1,2,3,4])
let set2 = new Set([3,4,5,6])
console.log(difference(set1, set2))//Set(2) { 1, 2 }

数组去重

const arr = [1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,45,5,5,6,6]
console.log([...new Set(arr)])
[
   1, 2, 3, 4,
  45, 5, 6
]

感谢MDN写出如此优秀的内容,跟着文章敲一遍感觉非常清晰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

️Dou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值