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 }
相关推荐
只想静静的3 分钟前
vue 自定义指令( 全局自定义指令 | 局部自定义指令 )
前端·javascript·vue.js
椰椰燕麦奶3 分钟前
【HOT100第四天】除自身以外数组的乘积,矩阵置零,螺旋矩阵,旋转图像
数据结构·算法·leetcode
jessezappy5 分钟前
日志:中文 URI 参数乱码之 encodeURI、encodeURIComponent、escape 作为 Ajax 中文参数编码给 ASP 的记录
javascript·中文乱码·uri·asp·escape
guokanglun8 分钟前
Vue模块化开发的理解
前端·javascript·vue.js
孑么1 小时前
Vue前端框架开发 npm安装Vite或CLI
前端·javascript·vue.js·typescript·前端框架·npm·node.js
孑么1 小时前
GDPU Vue前端框架开发 单文件组件
前端·javascript·vue.js·前端框架·npm·node.js·ecmascript
Kousi2 小时前
鸿蒙之ArkTS基础入门
前端·javascript·harmonyos
我总是词不达意2 小时前
uniapp vue3小程序报错Cannot read property ‘__route__‘ of undefined
前端·javascript·vue.js·小程序·uni-app
代码搬运媛2 小时前
vue 项目自动生成组件说明文档 styleguidist
前端·javascript·vue.js