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

如何优化50万+数组的Map与Filter去重逻辑以提升性能?

大数组Map转换+去重的性能优化方案

问题场景

手里有一个包含50万+条数据的数组,需要先对数组做Map转换提取指定字段,再筛选出唯一值,同时过滤空值。目前的两种实现方式在大数据量下性能极差,执行一次需要5-10分钟:

现有实现1:Filter + IndexOf

const getUniqueValues = (array: string[]): string[] => {
  return array.filter((item, index, _array) => _array.indexOf(item) === index);
};

const uniqueValues = getUniqueValues(
  editedData.map((bodyItem: any) => bodyItem[index])
).filter(Boolean);

现有实现2:Reduce + Includes

const uniqueValues = editedData.reduce(
  (accumulator, bodyItem) => {
    const item = bodyItem[index];
    if (!accumulator.includes(item)) {
      accumulator.push(item);
    }
    return accumulator;
  },
  []
);

性能瓶颈分析

这两种方案慢的核心原因都是线性查找带来的O(n²)时间复杂度:

  • 方案1先通过Map生成50万+条的临时数组,再用Filter遍历每个元素,每次调用indexOf都要从头遍历数组查找当前元素,总操作次数约为50万×50万=2.5e11次。
  • 方案2用Reduce遍历原数组,但每次判断accumulator.includes(item)时,都要遍历已收集的去重数组(最终长度21万),总操作次数约为50万×21万=1.05e11次,运算量远超硬件处理能力。

优化方案:利用Set实现O(n)时间复杂度

Set的add和has方法都是O(1)常数时间操作,我们可以在一次遍历中完成字段提取、空值过滤和去重,彻底降低时间复杂度:

优化实现1:Reduce + Set

const uniqueValues = Array.from(
  editedData.reduce((valueSet, bodyItem) => {
    const item = bodyItem[index];
    if (item) { // 过滤空值
      valueSet.add(item);
    }
    return valueSet;
  }, new Set<string>())
);

优化实现2:普通for循环(性能略优)

如果追求极致性能,普通for循环的运行开销比Reduce略低:

const valueSet = new Set<string>();
for (const bodyItem of editedData) {
  const item = bodyItem[index];
  if (item) {
    valueSet.add(item);
  }
}
const uniqueValues = Array.from(valueSet);

优化说明

  1. 时间复杂度从O(n²)降到O(n):只需要遍历原数组一次,每次操作都是常数时间,50万条数据的总操作次数仅为50万次左右,性能提升几个数量级。
  2. 减少内存占用:避免了生成50万+条的临时Map数组,直接用Set存储去重后的值(21万条),内存占用更低。
  3. 保留顺序:ES6+的Set会保留元素的插入顺序,转换为数组后,元素顺序和原数组中首次出现的顺序一致,和原有方案的结果顺序完全兼容。

对原有Reduce方案的修正

你之前写的Reduce逻辑是正确的,只是查找方式效率低,把数组替换成Set即可优化:

const uniqueValues = Array.from(
  editedData.reduce((accumulator, bodyItem) => {
    const item = bodyItem[index];
    if (item && !accumulator.has(item)) {
      accumulator.add(item);
    }
    return accumulator;
  }, new Set<string>())
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:30:28