【JavaScript】集合 Set & 映射 Map

Set 集合

类似于数组 Array,但 Set 里面不能有重复值、且 Set 元素的 [下标] & [值] 是一样的

let arr = ['a', 'b', 'a'];
console.log(arr); // [ 'a', 'b', 'a' ]

let set = new Set(arr);
console.log(set); // Set { 'a', 'b' }

初始化实例

  • 语法:new Set(arr),接收 1 个数组参数
let set = new Set(['a', 'b', 'c']);
console.log(set); // Set { 'a', 'b', 'c' }
  • 可以通过 Set 实例的 size 属性获取集合的长度
let set = new Set(['a', 'b', 'c']);
console.log(set.size); // 3

常用方法

set.add(XXX):添加元素
  • 只接收 1 个参数,后面的参数会被忽略
let set = new Set();
set.add('a', 'c');
console.log(set); // Set { 'a' }
  • 执行 add() 返回 Set 实例自身,所以可以 [链式调用]
let set = new Set();
set.add('a').add('b').add('c');
console.log(set); // Set { 'a', 'b', 'c' }
set.delete(XXX):删除元素
  • 只接收 1 个参数,后面的参数会被忽略
  • 返回 true-删除成功、false-删除失败
let set = new Set(['a', 'b', 'c']);
set.delete('a', 'b');
console.log(set); // Set { 'b', 'c' }
set.has(XXX):判断有没有指定值
  • 返回 true-有、false-无
let set = new Set(['a', 'b', 'c']);
console.log(set.has('a')); // true
console.log(set.has('s')); // false
set.clear():清空内容
  • 不需要参数、没有返回值
let set = new Set(['a', 'b', 'c']);
console.log(set); // Set { 'a', 'b', 'c' }
set.clear();
console.log(set) // Set {}

遍历元素

let set = new Set(['a', 'b', 'c']);
forEach()
set.forEach((value, index) => {
    console.log(value, index); // a a   b b   c c 
});
for … of
for (let item of set) { // 默认获取 values
    console.log(item); // a   b   c
}

for (let item of set.keys()) { // 使用 set.keys() → 遍历 key
    console.log(item); // a   b   c
}

for (let item of set.values()) { // 使用 set.values() → 遍历 value
    console.log(item); // a   b   c
}

for (let item of set.entries()) { // 使用 set.entries() → 遍历 [键值对]
    console.log(item); // [ 'a', 'a' ]   [ 'b', 'b' ]   [ 'c', 'c' ]
}

for (let [key, value] of set.entries()) { // 解构赋值 + set.entries() → 分别获取 [键值对]
    console.log(key, value); // a a   b b   c c
}
  • 可以发现,set 的 [下标] & [值] 是一样的

实用操作

集合 → 数组

转为数组后,能使用数组身上 set 不具有的一些方法,比如 map

① 使用扩展运算符 ...

let arr = [...new Set()];
let [...arr] = new Set();

② 使用方法 Array.from()

let arr = Array.from(new Set(['a', 'b', 'b'])); // ["a", "b"]
[数组] / [字符串] 去重
let arr = [1, 3, 5, 1, 2, 6, 3, 1, 5, 2]; // 数组
let newArr = [...new Set(arr)];
console.log(newArr); // [1, 3, 5, 2, 6]
let str = 'abcddbca'; // [字符串] 作为参数
let newStr = [...new Set(str)].join('');
console.log(newStr); // abcd
注意:
  1. Set 内部判断两个值是否不同,使用的算法叫做 “Same-value equality”,它类似于精确相等运算符 ===
    主要区别是:精确相等运算符认为 NaN != NaN,但前者认为 NaN === NaN
  2. 两个对象总是不相等的!!!
let arr = ['a', 'b', 'c'];
let set1 = new Set(arr);
let set2 = new Set(arr);
console.log(set1 == set2); // false

WeakSet

  • 弱集合 WeakSet 中的元素只能是 [Object] / [继承 Object 的] 类型
  • 但是,如果初始化时直接放入 [对象] 作为参数,又会报错;
    最好是:创建空 WeakSet 实例,然后用 add() 添加
let wSet = new WeakSet();
let obj = { name: "superman" };
wSet.add(obj);
console.log(wSet); // WeakSet {{…}}
WeakSet & Set
  1. WeakSet 实例没有 size 属性
  2. WeakSet 实例的 add(XXX)delete(XXX)has(XXX) 方法,需要传入 [对象] 作为参数
  3. WeakSet 实例不可迭代,不能使用 for … offorEach 循环,也不能使用 keys()values()entries() 方法

Map 映射

类似于对象,但是对象的 key 只能是字符串;map 的 key 可以为任意类型
就是说,Object 提供了 [字符串 ↔ 值] 的对应,Map 提供了 [值 ↔ 值] 的对应,是一种更完善的 Hash 结构

初始化实例

  • new Map([[key1, value1], [key2, value2], ...])
const map = new Map([['name', 'superman'], ['gender', 'male']]);
console.log(map); // Map { 'name' => 'superman', 'gender' => 'male' }
  • 可以通过 size 属性获取映射中的键值对的数量
let map = new Map([['name', 'superman']]);
console.log(map.size); // 1

常用方法

map.set(key, value):添加 key-value
  • 返回 map 自身,所以可以 [链式调用]
let map = new Map();
map.set('name', 'superman').set("age", 21)
console.log(map); // Map { 'name' => 'superman', 'age' => 21 }
map.get(key):获取指定 key 对应的 value
  • 查询成功则返回 value、否则返回 undefined
let map = new Map();
let obj = {};
map.set(obj, 'superman'); // key 为 [对象]
console.log(map.get(obj)); // superman
map.has(key):查看是否存在指定 key-value
  • 返回 true-存在、false-不存在
let map = new Map();
console.log(map.has("name")); // false
map.delete(key):删除指定 key-value
  • 删除成功返回 true、否则返回 false
let map = new Map();

let arr = [];
map.set(arr, 'superman'); // key 为 [数组]
console.log(map); // Map { [] => 'superman' }

map.delete(arr);
console.log(map); // Map {}
map.clear():清空映射
  • 无参数、无返回值
let map = new Map();

let fun = () => { };
map.set(fun, 'superman'); // key 为 [函数]
console.log(map); // Map { [Function: fun] => 'superman' }

map.delete(fun);
console.log(map); // Map {}

遍历属性

const map = new Map([['name', 'superman'], ['gender', 'male']]);
forEach()
map.forEach((item, index) => {
    console.log(item, index); // superman name   male gender
});
for … of
for (const item of map) { // 默认获取 key-value
    console.log(item); // [ 'name', 'superman' ]   [ 'gender', 'male' ]
}

for (const item of map.keys()) { // 使用 map.keys() → 遍历 key
    console.log(item); // name   gender
}

for (const item of map.values()) { // 使用 map.values() → 遍历 value
    console.log(item); // superman   male
}

for (const item of map.entries()) { // 使用 map.entries() → 遍历 [键值对]
    console.log(item); // [ 'name', 'superman' ]   [ 'gender', 'male' ]
}

Object & Map

  1. 内存占用
    给定固定大小的内存,Map 比 Object 多存储约 50% 的键值对
  2. 插入性能
    插入 Map 在所有浏览器中一般会稍微快一点
  3. 查找速度
    键值对较多的话,二者性能差异极小,或许 Object 稍快一些
  4. 删除性能
    使用 delete 删除 Object 属性的性能较差,为此出现了一些伪删除操作,包括把属性值设置为 undefined / null
    对大多数浏览器引擎来说,Map 的 delete() 操作更快。如果代码涉及大量删除操作,应选择 Map

WeakMap

  • WeakMap 是弱映射
  • WeakMap 实例的 key 必须是 [Object] / [继承 Object 的] 类型
    如果 key 不是 [对象],就会报错
let obj = {};
let wMap = new WeakMap([[obj, 'superman']]);
console.log(wMap); // WeakMap {{…} => 'superman'}
console.log(wMap.get(obj)); // superman
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JS.Huang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值