ES6数据类型----Map的使用及例子说明

目录

含义和基本用法

常用方法

举例说明

Map的实际应用

注意点

Map结构原生方法


ES6 提供了 Map 数据结构。它类似于对象,是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。

含义和基本用法

Map对象是JavaScript中的一个内置对象,它是一种有序的键值对集合,Map对象的结构如下所示:

Map {
  key1=>value1,
  key2=>value2,
  key3=>value3
  ……
}

在Map对象中,键和值是成对出现的,用=>运算符连接,每个键唯一,且可以是任意类型的值,(包括对象,函数和基本数据类型),而且值也可以是任意类型

可以通过调用Map的方法来添加、获取和修改键值对。

以下是一些常用的方法:

常用方法

  1. 创建 Map:使用 new Map() 创建一个空的 Map 对象。

    const map = new Map();
    
  2. 添加键值对:使用 map.set(key, value) 方法向 Map 中添加键值对。

    map.set('key1', 'value1');
    map.set('key2', 'value2');
    
  3. 获取值:使用 map.get(key) 方法根据键获取对应的值。

    const value1 = map.get('key1'); // 返回 'value1'
    
  4. 检查键是否存在:使用 map.has(key) 方法判断 Map 是否包含特定的键。

    const hasKey = map.has('key1'); // 返回 true
    
  5. 删除键值对:使用 map.delete(key) 方法删除 Map 中的键值对。

    map.delete('key2');
    
  6. 清空 Map:使用 map.clear() 方法清空 Map 中的所有键值对。

    map.clear();
    
  7. 遍历 Map:可以使用 for...of 循环、forEach() 方法或者使用 Map 的迭代器来遍历 Map 中的键值对。

    // 使用 for...of 循环遍历 Map
    for (let [key, value] of map) {
      console.log(key, value);
    }
    
    // 使用 forEach() 方法遍历 Map
    map.forEach((value, key) => {
      console.log(key, value);
    });
    
    // 使用 Map 的迭代器遍历 Map
    const mapIterator = map.entries();
    for (let entry of mapIterator) {
      console.log(entry);
    }
    
  8. 获取 Map 的大小:使用 map.size 属性获取 Map 中键值对的数量。

    const size = map.size; // 返回 Map 大小

举例说明

使用Map对象可以方便地存储和查找数据,尤其适合于需要维护键值对关系的情况。

// 创建一个新的Map对象
let map = new Map();
// 向Map中添加键值对
map.set("name", "John");
map.set("age", 30);
map.set("city", "New York");

// 获取 Map 中的值
console.log(map.get("name")); // 输出:John
console.log(map.get("age")); // 输出:30

// 检查 Map 中是否存在指定的键
console.log(map.has("city")); // 输出:true
console.log(map.has("country")); // 输出:false

// 删除 Map 中的键值对
map.delete("age");

// 清空 Map 中的所有键值对
map.clear();

// 获取 Map 中键值对的数量
console.log(map.size); // 输出:0

Map的实际应用

// 下面是一些实际应用场景的例子,展示了如何使用 Map:

// 1、缓存数据:
// 创建一个用于缓存数据的 Map 对象
let cache = new Map();

function getDataFromCache(key) {
  if (cache.has(key)) {
    // 如果缓存中存在该键,则从缓存中获取对应数据
    return cache.get(key);
  } else {
    // 否则进行数据计算,并将计算结果缓存起来
    let data = computeData();
    cache.set(key, data);
    return data;
  }
}
// 这个例子中,cache 是一个用于缓存数据的 Map 对象。通过 getDataFromCache 函数,在每次需要获取数据时,先检查缓存中是否已经存在相应的数据。如果存在,则直接从缓存中获取数据;如果不存在,则进行数据计算,并将计算结果缓存到 Map 对象中。


// 2、统计元素出现次数:
let arr = [1, 2, 3, 2, 1, 3, 2, 1, 1, 3];
let countMap = new Map();

// 遍历数组,统计元素出现次数
arr.forEach((element) => {
  if (countMap.has(element)) {
    countMap.set(element, countMap.get(element) + 1);
  } else {
    countMap.set(element, 1);
  }
});

// 输出元素出现次数
//forEach() 方法可以在 Map 对象上进行迭代操作,遍历其中的所有键值对。它接受一个回调函数作为参数,并在每次迭代中执行该回调函数。回调函数可以接受三个参数:值、键和 Map 对象本身。顺序是:值、键、Map。注意,回调函数中的参数顺序与传入的参数顺序是固定的。
countMap.forEach((count, element) => {   
  console.log(`${element} 出现了 ${count} 次`);
});
// 这个例子中,通过遍历数组 arr,使用 Map 对象 countMap 统计了数组中每个元素的出现次数。遍历过程中,通过判断 Map 中是否已有键来更新对应的计数值,或者添加新的键并设置初始计数值为 1。最后,使用 forEach 方法遍历 Map 对象,输出每个元素的出现次数。



// 3、存储用户信息:
let user1 = { id: 1, name: "Alice", age: 25 };
let user2 = { id: 2, name: "Bob", age: 30 };
let user3 = { id: 3, name: "Charlie", age: 35 };

let userMap = new Map();

// 添加用户信息到 Map 对象
userMap.set(user1.id, user1);
userMap.set(user2.id, user2);
userMap.set(user3.id, user3);

// 获取用户信息
let userId = 2;
let userInfo = userMap.get(userId);
console.log(userInfo);
// 这个例子中,使用 Map 对象 userMap 存储了用户信息。每个用户对象作为值,用户 ID 作为键。
通过调用 set() 方法将用户信息添加到 Map 对象中。然后,可以通过调用 get() 方法,并传入用户 ID,来获取相应的用户信息。

// 这些例子展示了 Map 的一些实际应用场景,但还有许多其他用法和变体,根据具体需求可以进一步灵活应用。

注意点

只有对同一个对象的引用,Map 结构才将其视为同一个键。这一点要非常小心。

const map = new Map();
map.set(['a'], 555);
map.get(['a'])  // 输出: undefined

// 上面代码的set和get方法,表面是针对同一个键,但实际上这是两个不同的数组实例,内存地址是不一样的,因此get方法无法读取该键,返回undefined。

// 当调用 map.set(['a'], 555) 时,你将一个包含单个元素 ['a'] 的数组作为键插入到 Map 中,并将对应的值设置为 555。然而,当你调用 map.get(['a']) 时,你使用了一个新创建的数组 ['a'] 作为键来获取对应的值。由于在 JavaScript 中,对于引用类型(如数组、对象)的比较是基于引用的,而不是基于值的,所以你传递给 map.get() 的新数组和最初设置的数组实际上是不完全相等的,即使它们的元素看起来相同。
// 因此,map.get(['a']) 返回的是 undefined,因为 Map 中并没有存储使用新数组作为键的对应值。

// 为了使 map.get(['a']) 返回预期的值 555,你应该使用相同的数组引用作为键,如下所示:
const map = new Map();
const key = ['a'];
map.set(key, 555);
map.get(key)  // 输出: 555

// 同理,同样的值的两个实例,在 Map 结构中被视为两个键。
const map = new Map();
const k1 = ['a'];
const k2 = ['a'];

// 尽管 k1 和 k2 看起来是相同的数组,并且它们的元素也相同,但它们是两个不同的数组实例。因此,它们的引用是不相等的。

map
.set(k1, 111)
.set(k2, 222);
// 当你调用 map.set(k1, 111) 时,你将 k1 数组作为键插入到 Map 中,并将对应的值设置为 111。接下来,当你调用 map.set(k2, 222) 时,你使用另一个数组 k2 作为键,将对应的值设置为 222。
// 由于 k1 和 k2 是不同的数组实例,它们的引用是不相等的。因此,Map 将这两个键视为两个不同的键,并且存储了各自对应的值。

map.get(k1) // 111
map.get(k2) // 222

Map结构原生方法

Map 结构原生提供三个遍历器生成函数和一个遍历方法。

  • Map.prototype.keys():返回键名的遍历器。
  • Map.prototype.values():返回键值的遍历器。
  • Map.prototype.entries():返回所有成员的遍历器。
  • Map.prototype.forEach():遍历 Map 的所有成员。

需要特别注意的是,Map 的遍历顺序就是插入顺序。

// keys(): 返回一个包含 Map 中所有键的迭代器。
const map = new Map();
const keys = map.keys();
for (let key of keys) {
  console.log(key);
}

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"

// values(): 返回一个包含 Map 中所有值的迭代器。
for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"

// entries(): 返回一个包含 Map 中所有键值对的迭代器。
const entries = map.entries();
for (let [key, value] of entries) {
  console.log(key, value);
}

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"
// map.entries() 是 Map 对象的一个方法,它返回一个包含 Map 中所有键值对的迭代器。每个键值对都以数组的形式表示,其中索引 0 是键,索引 1 是对应的值。该方法的作用是可以遍历 Map 中的所有键值对。

// 下面是一个使用 map.entries() 的示例:
const map = new Map();
map.set('key1', 'value1');
map.set('key2', 'value2');

const entries = map.entries();
for (let entry of entries) {
  console.log(entry);  // 输出: ['key1', 'value1'], ['key2', 'value2']
}

// 或者使用解构赋值来访问键和值
for (let [key, value] of map.entries()) {
  console.log(key, value);  // 输出: 'key1', 'value1', 'key2', 'value2'
}

// 将 entries 转换成数组
const entriesArray = Array.from(map.entries());
console.log(entriesArray);  // 输出: [['key1', 'value1'], ['key2', 'value2']]
// 在上述示例中,首先创建一个 Map 对象 map,并使用 set() 方法添加了两个键值对。然后,通过 map.entries() 获得一个包含所有键值对的迭代器。接着使用 for...of 循环遍历 entries,每次迭代得到一个由键和值组成的数组。我们也可以使用解构赋值来直接访问键和值。最后,使用 Array.from() 将 entries 转换成数组。

Map结构转化为数组结构,比较快速的方法就是使用扩展运算符(...)

const map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

[...map.keys()]
// [1, 2, 3]

[...map.values()]
// ['one', 'two', 'three']

[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]

[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值