You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript forEach迭代时统计剩余元素出现次数的高效实现方案

二维数组迭代连续计数优化需求

需求描述

使用forEach遍历二维数组时,每轮迭代需要统计当前及之后剩余迭代中,当前子数组内各元素的连续出现次数(元素出现中断后再出现需分段统计),最终输出每轮对应的计数结果。

实际场景测试数组

const blocks = [
  ['A', 'B', 'C'],
  ['A', 'B', 'C'],
  ['B', 'D', 'E'],
  ['A', 'B', 'D', 'E'],
  ['A', 'B', 'F', 'G'],
  ['A', 'B', 'F', 'G'],
  ['A', 'B', 'F', 'H', 'I']
];

该场景下要求对元素A的两段连续出现分别统计:第一段连续出现2次,第二段连续出现4次。

优化实现方案

优化点说明

  • 用Set存储字符集合,has查询效率远高于数组includes方法
  • 用Map存储计数映射,替代原实现中的find查找,查询复杂度从O(n)降至O(1)
  • 统计遍历增加终止条件:待统计的字符全部消失后直接停止后续遍历,减少无效执行
  • 精简冗余变量,逻辑更简洁易读

优化后代码

const blocks = [
  ['A', 'B', 'C'],
  ['A', 'B', 'C'],
  ['B', 'D', 'E'],
  ['A', 'B', 'D', 'E'],
  ['A', 'B', 'F', 'G'],
  ['A', 'B', 'F', 'G'],
  ['A', 'B', 'F', 'H', 'I']
];

const results = [];
let lastBlockSet = new Set();

blocks.forEach((currBlock, index, arr) => {
  // 筛选当前轮次需要统计的新增字符(上一轮没有的字符)
  const currBlockSet = new Set(currBlock);
  const statChars = [...currBlockSet].filter(char => !lastBlockSet.has(char));
  lastBlockSet = currBlockSet;

  // 初始化计数Map和待统计字符集合
  const countMap = new Map(statChars.map(char => [char, 0]));
  let remainStatChars = new Set(statChars);

  // 遍历当前及之后的子数组统计连续次数
  for (let i = index; i < arr.length && remainStatChars.size > 0; i++) {
    const loopBlockSet = new Set(arr[i]);
    // 过滤出当前子数组中仍存在的待统计字符
    remainStatChars = new Set([...remainStatChars].filter(char => loopBlockSet.has(char)));
    // 计数加1
    remainStatChars.forEach(char => countMap.set(char, countMap.get(char) + 1));
  }

  // 转换为要求的输出格式
  const currResult = statChars.map(char => ({ block: char, duration: countMap.get(char) }));
  results.push(currResult);
  console.log(currResult);
});

内容的提问来源于stack exchange,提问作者Fran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:06:08