ES6 Set和Map数据结构用法详解

文章目录

前言

在ES6(ECMAScript 2015)引入了两种新的数据结构:Set 和 Map。这两种数据结构提供了更加高效的数据存储和检索方式,以下是它们的特性和用法

Set 数据结构

Set 是一种集合数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。Set中的每个值只能出现一次,这意味着你可以使用 Set 来过滤掉数组中的重复元素。

创建Set

js 复制代码
let mySet = new Set();

// 例一
const mySet2 = new Set([1, 2, 3, 4, 4]);
console.log([...mySet]) // [1, 2, 3, 4]

// 例二
const mySet3 = new Set([1, 2, 3, 4, 5, 6, 6, 7,6,3]);
mySet3.size // 7

添加元素

Set不会添加重复的值

js 复制代码
let mySet = new Set();

mySet.add(1);
mySet.add('some text');
mySet.add({a: 3});

删除元素

删除某个值,返回一个布尔值,表示删除是否成功。

js 复制代码
const mySet = new Set([1, 2, 3, 4, 4]);
mySet.delete(1); // 删除值为 1 的元素

删除所有数据

js 复制代码
const mySet = new Set([1, 2, 3, 4, 4]);

mySet.clear(); // 移除所有元素

获取set的大小(类似于数组的长度)

js 复制代码
console.log(mySet.size); // 返回 Set 中元素的数量

检查是否包含某个元素

返回一个布尔值,表示该值是否为Set的成员。

js 复制代码
const mySet = new Set([1, 2, 3, 4, 4]);
let hasOne = mySet.has(1); // 返回 true 或 false

四种遍历set的方法

1.for...of循环
js 复制代码
let mySet = new Set([1, 8, 5, 9, 10]);

for (let value of mySet) {
    console.log(value); // 1,8,5,9,10;依次打印Set中的值
}
2.forEach方法

Set 对象有一个 forEach 方法,该方法接受一个回调函数作为参数,这个回调函数会在每次迭代时被调用,同时传递当前值、当前值(因为 Set 只有值)、以及 Set 本身作为参数。

js 复制代码
let mySet = new Set([1, 8, 5, 9, 10]);

mySet.forEach(function(value) {
    console.log(value);
});

// 使用箭头函数
mySet.forEach(value => console.log(value));
3.转换为数组后使用 for 循环

Set 转换成数组,然后利用数组的方法进行操作。可以使用扩展运算符 ... 或者 Array.from() Set 转换成数组,之后就可以使用传统的 for 循环或者数组的其他方法来遍历了。

js 复制代码
let mySet = new Set([1, 8, 5, 9, 12]);

// 使用扩展运算符
let arrayFromSet = [...mySet];
for (let i = 0; i < arrayFromSet.length; i++) {
    console.log(arrayFromSet[i]);
}

// 使用 Array.from()
let anotherArray = Array.from(mySet);
for (let i = 0; i < anotherArray.length; i++) {
    console.log(anotherArray[i]);
}
4.keys(),values(),entries()

虽然 Set 只有值没有键,但为了保持与其他数据结构的一致性,Set 仍然提供了 keys(), values(), 和 entries() 方法。这些方法返回的都是迭代器对象,可以配合 for...of 循环使用。

  • keys()
    keys()方法返回的值和values()实际上上相同的结果,因为set中键就是值
js 复制代码
let mySet = new Set([1, 8, 5, 9, 12]);
for (let key of mySet.keys()) {
    console.log(key);
}


const mySet2 = new Set(['html', 'css', 'js']);
const keysArray = Array.from(mySet2.keys());
console.log(keysArray); // 输出: ['html', 'css', 'js']
  • values()
    values() 方法返回一个新的迭代器对象,它包含了 Set 对象中每个元素的值。
js 复制代码
const mySet = new Set([1, 2, 3, 4, 4]);

for (let value of mySet.values()) {
    console.log(value);
}

// 过滤出满足条件的值
const mySet2 = new Set([1, 3, 4.5,0.75, 1.25, 2.5, 3.75, 5]);
const filteredValues = Array.from(mySet2.values()).filter(num => num > 1 && num < 4);
console.log(filteredValues); // 输出: [3,1.25, 2.5, 3.75]
  • entries()
    entries() 方法返回 [value, value] 形式的数组,其中两个值相同,这与 Map 的 entries() 不同。
js 复制代码
let mySet = new Set([1, 8, 5, 9, 12]);

for (let entry of mySet.entries()) {
    console.log(entry); // [value, value]
}

//使用 entries() 和解构来遍历 Set
const mySet2 = new Set(['html', 'css', 'js']);
for (const [key, value] of mySet2.entries()) {
    console.log(`Key: ${key}, Value: ${value}`);
}
// 输出:
// Key: html, Value: html
// Key: css, Value: css
// Key: js, Value: js

集合运算方法

  • .union()是并集运算,返回包含两个Set中存在的所有元素的集合
js 复制代码
const mySet1 = new Set(["js", "html", "css"]);
const mySet2 = new Set(["Python", "Java", "js"]);

const all = mySet1.union(mySet2);
// 输出: {"js", "html", "css", "Python", "Java"}
  • .intersection()是交集运算,返回同时包含在两个Set中的成员
js 复制代码
const mySet1 = new Set(["js", "html", "css"]);
const mySet2 = new Set(["Python", "Java", "js"]);

const newSet = mySet1.intersection(mySet2);
// 输出: {"js"}
  • .difference()是差集运算,返回第一个集合中存在但第二个集合中不存在的所有元素的集合。
js 复制代码
const mySet1 = new Set(["js", "html", "css"]);
const mySet2 = new Set(["Python", "Java", "js"]);

const newSet1 = mySet1.difference(mySet2);
// Set {"html", "css"}

const newSet2 = mySet2.difference(mySet1);
// Set {"Python", "Java"}
  • .isSubsetOf()返回一个布尔值,判断第一个集合是否为第二个集合的子集,即第一个集合的所有元素是否都是第二个集合中的元素
js 复制代码
const mySet1 = new Set(["js", "html", "css"]);
const mySet2 = new Set(["Python", "Java", "js"]);

mySet2.isSubsetOf(mySet1);
// true

mySet1.isSubsetOf(mySet2);
// false

Map数据结构

Map 是一种键值对的集合,任何类型的值(包括对象)都可以作为键或值。与对象不同的是,Map 的键是有序的,所以当你遍历它的时候,会按照插入顺序来。

创建Map

js 复制代码
let myMap = new Map()

添加元素(设置键值对)

js 复制代码
let myMap = new Map()

myMap.set('name', '张三');
myMap.set(1, 'one');
myMap.set(true, 7);

// 输出:
// new Map([
//     [
//         "name",
//         "张三"
//     ],
//     [
//         1,
//         "one"
//     ],
//     [
//         true,
//         7
//     ]
// ])

删除元素

js 复制代码
let myMap = new Map([
  ['name','张三'],
  ['age','18']
])

myMap.delete('name'); // 删除键为 'name' 的键值对

删除所有数据

js 复制代码
let myMap = new Map([
  ['name','张三'],
  ['age','18']
])

myMap.clear(); // 移除所有键值对

获取Map的大小

js 复制代码
let myMap = new Map([
  ['name','张三'],
  ['age','18']
])

// 返回 Map 中键值对的数量; 
console.log(myMap.size);//输出:2

检查键是否存在

检查是否存在某个数据,返回布尔值

js 复制代码
let myMap = new Map([
  ['name','张三'],
  ['age','18']
])

let hasName = myMap.has('name'); // true

Map的3种遍历方法

1.forEach

forEach方法允许你为Map中的每一个键值对执行一个函数。这个函数可以接收三个参数:值,键和Map对象本身

js 复制代码
myMap.forEach((value, key, map) => {
  console.log(`${key} = ${value}`);
});
2.使用 for...of 循环遍历 entries()

entries() 方法返回一个新的迭代器对象,它包含了 Map 对象中每个元素的 [key, value] 数组形式的条目。使用 for...of 循环可以直接遍历这些条目

js 复制代码
const myMap = new Map([
  ['name', 'Alice'],
  ['age', 18],
  ['city', 'Wonderland']
]);

for (const [key, value] of myMap.entries()) {
  console.log(`${key}: ${value}`);
}
3.使用 for...of 循环遍历 keys() 和 values()
  • keys() :返回一个新的迭代器对象,包含了Map对象中每个元素的键
  • values():返回一个新的迭代器对象,包含了Map对象中每个元素的值
js 复制代码
const myMap = new Map([
  ['name', 'Alice'],
  ['age', 18],
  ['city', 'Wonderland']
]);

// 遍历键
for (const key of myMap.keys()) {
  console.log(key);
}

// 遍历值
for (const value of myMap.values()) {
  console.log(value);
}

Map类型转换

1.Map转换为数组
js 复制代码
const myMap = new Map([
 ['name', 'Alice'],
 ['age', 18],
 ['city', 'Wonderland']
]);

// 使用扩展运算符
const entriesArray = [...myMap.entries()];
console.log(entriesArray); // 输出: [['name', 'Alice'], ['age', 18], ['city', 'Wonderland']]

// 使用 Array.from()
const keysArray = Array.from(myMap.keys());
const valuesArray = Array.from(myMap.values());
const mapToArray = Array.from(myMap);
console.log(keysArray); // 输出: ['name', 'age', 'city']
console.log(valuesArray); // 输出: ['Alice', 18, 'Wonderland']
console.log(mapToArray); // 输出: [['name', 'Alice'], ['age', 18],['city','Wonderland']]

// 使用数组方法,比如 map
const keyValuePairs = Array.from(myMap).map(([key, value]) => ({ key, value }));
console.log(keyValuePairs); // 输出: [{key: 'name', value: 'Alice'}, {key: 'age', value: ¾}, {key: 'city', value: 'Wonderland'}]
2.数组转换Map

将数组转换为 Map 可以通过 Map构造函数完成,只要数组的元素是键值对的形式

js 复制代码
const arrayToMap = new Map([
  ['name', 'Alice'],
  ['age', 18]
]);
console.log(arrayToMap); 
// 输出: Map(2) { 'name' => 'Alice', 'age' => 18 }
3.Map转换对象

Map转换为普通对象可以使用 Object.fromEntries() 方法,这个方法接受一个键值对数组并返回一个对象

js 复制代码
const myMap = new Map([
  ['name', 'Alice'],
  ['age', 18],
  ['city', 'Wonderland']
]);
const myObj = Object.fromEntries(myMap);
console.log(myObj); 
// 输出: { name: 'Alice', age: 18, city: 'Wonderland' }
4.对象转换Map

普通对象转换为 Map 可以通过Object.entries()方法,它返回一个给定对象自身可枚举属性的键值对数组,然后使用这个数组初始化 Map

js 复制代码
const obj = { name: 'Bob', age: 25, city: 'New York' };
const newMap = new Map(Object.entries(obj));
console.log(newMap); 
// 输出: Map(3) { 'name' => 'Bob', 'age' => 25, 'city' => 'New York' }
5.Map转换JSON

Map 直接转换为 JSON 字符串需要首先将 Map 转换为对象,然后再使用 JSON.stringify() 方法将其转换为 JSON 字符串。

js 复制代码
const myMap = new Map([['name', 'Alice'], ['age', 18]]);
const mapToObject = Object.fromEntries(myMap);
const mapToJson = JSON.stringify(mapToObject);
console.log(mapToJson); 
// 输出: '{"name":"Alice","age":18}'
6.JSON转换Map

JSON 字符串转换为 Map,你需要先解析 JSON 字符串得到一个对象,然后将这个对象转换为 Map

js 复制代码
const jsonStr = '{"name":"Alice","age":18}';
const obj = JSON.parse(jsonStr);
const jsonToMap = new Map(Object.entries(obj));
console.log(jsonToMap); 
// 输出: Map(2) { 'name' => 'Alice', 'age' => 18 }
相关推荐
axxy200026 分钟前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法
2401_857600951 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_857600951 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js
GDAL1 小时前
vue入门教程:组件透传 Attributes
前端·javascript·vue.js
小白学大数据1 小时前
如何使用Selenium处理JavaScript动态加载的内容?
大数据·javascript·爬虫·selenium·测试工具
2402_857583491 小时前
基于 SSM 框架的 Vue 电脑测评系统:照亮电脑品质之路
前端·javascript·vue.js
Uu_05kkq2 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
java_heartLake2 小时前
Vue3之性能优化
javascript·vue.js·性能优化
Swift社区2 小时前
HarmonyOS 实践 - 设计模式在代码中的作用
javascript
少年姜太公3 小时前
从零开始详解js中的this(下)
前端·javascript·程序员