首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >如何提取 Map 的第 i 个元素?一文教你玩转迭代器对象

如何提取 Map 的第 i 个元素?一文教你玩转迭代器对象

作者头像
watermelo37
发布2025-10-14 08:47:17
发布2025-10-14 08:47:17
1080
举报
文章被收录于专栏:前端专精前端专精

**作者**:watermelo37 CSDN全栈领域优质创作者、万粉博主、华为云云享专家、阿里云专家博主、腾讯云“创作之星”特邀作者、支付宝合作作者,全平台博客昵称watermelo37。 一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。undefined 温柔地对待温柔的人,包容的三观就是最大的温柔。undefined

如何提取 Map 的第 i 个元素?一文教你玩转迭代器对象

一、关于Map对象的设计与思考

代码语言:txt
复制
    在前端开发中,我们经常用 Map 来存储键值对,比如缓存接口请求结果、维护用户状态或统计访问数据。最常用的 Map 基本方法包括get / set / has,可Map能不能像数组那样,获取第 i 个元素呢?
代码语言:txt
复制
    首先我们可以迅速想到,Map的添加是有顺序的,按顺序提取绝对可行,那么我们可以写一个新对象,比如叫orderMap,它既支持map的原生方法,又可以像数组那样获取第 i 个元素:
代码语言:javascript
复制
function createOrderMap() {
  const keys = [];
  const values = [];

  return {
    set(key, value) {
      const index = keys.indexOf(key);
      if (index >= 0) {
        // key 已存在,更新对应 value
        values[index] = value;
      } else {
        // key 不存在,新增
        keys.push(key);
        values.push(value);
      }
    },
    // 按索引访问元素,返回 [key, value]
    getByIndex(i) {
      if (i < 0 || i >= keys.length) return undefined;
      return [keys[i], values[i]];
    },
    length() {
      return keys.length;
    }
    // ...还有has、get等方法暂不实现
  };
}

// 测试
const orderMap = createOrderMap();
orderMap.set('a', 1);
orderMap.set('b', 2);
orderMap.set('c', 3);

// 覆盖 b
orderMap.set('b', 22);

console.log(orderMap.getByIndex(0)); // ['a', 1]
console.log(orderMap.getByIndex(1)); // ['b', 22]
console.log(orderMap.getByIndex(2)); // ['c', 3]
console.log(orderMap.length());      // 3
代码语言:txt
复制
    当然上述只是一种处于技术偏好的“玩耍”,那原生的Map对象到底是不是有序的呢?答案是肯定的。在特定操作下,我们可以像数组一样“按顺序访问元素”。那原生Map对象如何获取第二个元素呢?

二、实战场景模拟

1、场景设计
代码语言:txt
复制
    假设我们在做一个用户访问记录的功能,每次用户访问页面时,我们把用户 ID 和访问时间记录在 Map 里:
代码语言:javascript
复制
const userVisits = new Map();
userVisits.set('user1', '2025-08-31T09:00:00');
userVisits.set('user2', '2025-08-31T09:05:00');
userVisits.set('user3', '2025-08-31T09:10:00');
代码语言:txt
复制
    现在我们想获取第二个访问的用户信息,即 Map 中的第二个 [key, value] 对。
2、方案一:转换为数组
代码语言:txt
复制
    Map 可以通过 Array.from() 转成数组,然后用索引直接访问:
代码语言:javascript
复制
const secondEntry = Array.from(userVisits)[1];

console.log(secondEntry);     // ['user2', '2025-08-31T09:05:00']
console.log(secondEntry[0]);  // 'user2'
console.log(secondEntry[1]);  // '2025-08-31T09:05:00'
代码语言:txt
复制
    这样语法简单,直接通过索引访问。但是Map 转成数组会创建一个新数组,如果 Map 很大,会消耗额外内存。
3、方案二:使用迭代器对象
代码语言:txt
复制
    Map 本身是可迭代对象,它的 entries()、keys()、values() 方法返回的都是 迭代器(Iterator)。迭代器允许我们按顺序访问每一个元素,而不需要转成数组。
代码语言:javascript
复制
const iterator = userVisits.entries(); // entries() 返回 [key, value] 迭代器
iterator.next(); // 跳过第一个
const second = iterator.next().value;

console.log(second);     // ['user2', '2025-08-31T09:05:00']
console.log(second[0]);  // 'user2'
console.log(second[1]);  // '2025-08-31T09:05:00'
代码语言:txt
复制
    看到这里,熟悉Array.from()的开发者可能已经发现了什么:Map 之所以能用 Array.from() 转换为数组,是因为它是一个实现了 [Symbol.iterator] 的可迭代对象,Array.from() 能够将任何可迭代对象(或类数组对象)转换为数组。对于 Map 而言,它的默认迭代结果是 [key, value] 形式的 entry,因此 Array.from(map) 得到的是一个二维数组。
4、map / set 获取第 i 个元素
代码语言:txt
复制
    set可以直接利用可迭代对象的性质来遍历:
代码语言:javascript
复制
let set = new Set([10, 20, 30]);

let i = 0;
let targetIndex = 1; // 想取第 2 个元素
for (let item of set) {
  if (i === targetIndex) {
    console.log(item); // 20
    break;
  }
  i++;
}
代码语言:txt
复制
    或者一样转换成迭代器再用next():
代码语言:javascript
复制
const set = new Set([10, 20, 30]);

// 1. 获取迭代器
const iterator = set.values();

// 2. 调用 next()
console.log(iterator.next()); // { value: 10, done: false }
console.log(iterator.next()); // { value: 20, done: false }
console.log(iterator.next()); // { value: 30, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
代码语言:txt
复制
    也可以封装一个迭代器获取方法,这样set、map,甚至普通数组和字符串都可以通用了:
代码语言:javascript
复制
function getNth(iterable, n) {
  let iter = iterable[Symbol.iterator]();
  let result;
  while (n-- >= 0) {
    result = iter.next();
    if (result.done) return undefined; // 超出范围
  }
  return result.value;
}

console.log(getNth(new Set([10, 20, 30]), 2)); // 30
console.log(getNth("hello", 1)); // "e"

三、可迭代对象和迭代器是什么?

1、迭代器本质
代码语言:txt
复制
    迭代器是一个对象,遵循 { value, done } 结构,value 是当前元素,done 是布尔值表示是否遍历完。
2、可重复使用吗?
代码语言:txt
复制
    **不可以**,迭代器是一次性的。如果想重新遍历,必须重新调用 entries() 或 keys() / values()。

熟悉数据结构的开发者可以把他理解成一个单向链表

代码语言:javascript
复制
// 遍历迭代器,无法回头望
const it2 = userVisits.entries();
for (const [user, time] of it2) {
  console.log(user, time);
}
3、迭代器和可迭代对象有什么区别
代码语言:txt
复制
    只要一个对象实现了 Symbol.iterator 方法,就叫可迭代对象。比如 Array、String、Set、Map、arguments、NodeList 等。
代码语言:txt
复制
    它们可以用:for...of、扩展运算符 ...、Array.from()、解构赋值 [a, b, c] = ...
代码语言:txt
复制
    但是它们自己不一定有 next() 方法。
代码语言:txt
复制
    迭代器是实现了 next() 方法的对象,且next() 返回一个 { value, done } 对象。迭代器是真正“驱动”迭代过程的东西。
4、应用场景
代码语言:txt
复制
    使用的时候搭配 for...of 循环遍历即可,语法简洁。
  • 想按顺序访问 Map 或 Set 元素
  • 想实现延迟遍历,只取前几个元素,节省内存

四、结语

代码语言:txt
复制
    提取 Map 第二个元素的常用方法:①转成数组(简单直观,但有内存开销)。②使用迭代器(更灵活、节省内存)。
代码语言:txt
复制
    迭代器每次调用 .next() 返回 { value, done },可以控制遍历流程,比如“跳过前几个元素”或“取前 n 个元素”。
代码语言:txt
复制
    只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
代码语言:txt
复制
    其他热门文章,请关注:

极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图

你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

Web Worker:让前端飞起来的隐形引擎

通过array.filter()实现数组的数据筛选、数据清洗和链式调用

DeepSeek:全栈开发者视角下的AI革命者

测评:这B班上的值不值?在不同城市过上同等生活水平到底需要多少钱?

通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能

TreeSize:免费的磁盘清理与管理神器,解决C盘爆满的燃眉之

通过MongoDB Atlas 实现语义搜索与 RAG——迈向AI的搜索机制

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

前端实战:基于Vue3与免费满血版DeepSeek实现无限滚动+懒加载+瀑布流模块及优化策略

【前端实战】如何让用户回到上次阅读的位置?

el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

JavaScript双问号操作符(??)详解,解决使用 || 时因类型转换带来的问题

高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

内存泄漏——海量数据背后隐藏的项目生产环境崩溃风险!如何避免内存泄漏

MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver

JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、DOM操作等

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何提取 Map 的第 i 个元素?一文教你玩转迭代器对象
    • 一、关于Map对象的设计与思考
    • 二、实战场景模拟
      • 1、场景设计
      • 2、方案一:转换为数组
      • 3、方案二:使用迭代器对象
      • 4、map / set 获取第 i 个元素
    • 三、可迭代对象和迭代器是什么?
      • 1、迭代器本质
      • 2、可重复使用吗?
      • 3、迭代器和可迭代对象有什么区别
      • 4、应用场景
    • 四、结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档