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

如何高效过滤含重复属性的JavaScript数组?(数据量超500)

问题描述

我有如下结构的JavaScript数组:

const foodsList = [
  {
    foodOrigin: "Padang",
    foodName: "Nasi Padang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Padang",
    foodName: "Gulai",
    originCode: "PDN"
  },
  {
    foodOrigin: "Padang",
    foodName: "Rendang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Palembang",
    foodName: "Pempek",
    originCode: "PLG"
  },
  {
    foodOrigin: "Palembang",
    foodName: "Tekwan",
    originCode: "PLG"
  },
  {
    foodOrigin: "Yogyakarta",
    foodName: "Gudeg",
    originCode: "YKT"
  }
];

希望将该数组过滤为仅保留每个唯一originCode对应的foodOrigin与originCode的数组,目标结果如下:

const filteredFoodsList = [
  {
    foodOrigin: "Padang",
    originCode: "PDN"
  },
  {
    foodOrigin: "Palembang",
    originCode: "PLG"
  },
  {
    foodOrigin: "Yogyakarta",
    originCode: "YKT"
  }
];

目前我通过以下双重循环的方式实现了需求,但实际数据量超过500条,请问是否有更简洁高效的实现方法?

const filteredFoodsList = [];
for (let i = 0; i < foodsList.length; i++) {
  if (i === 0) {
    filteredFoodsList.push({
      originCode: foodsList[i].originCode,
      foodOrigin: foodsList[i].foodOrigin
    });
  }
  let isExist = false;
  for (let j = 0; j < filteredFoodsList.length; j++) {
    if (foodsList[i].originCode === filteredFoodsList[j].originCode) {
      isExist = true;
    }
  }
  if (!isExist) {
    filteredFoodsList.push({
      originCode: foodsList[i].originCode,
      foodOrigin: foodsList[i].foodOrigin
    });
  }
}
高效实现方案

你的双重循环时间复杂度为O(n²),数据量超过500条时性能会明显下降。下面几种方法均为O(n)时间复杂度,更简洁高效:

方法1:使用Map去重

利用Map的键唯一性,遍历数组时以originCode为键存储目标对象,最后提取Map的所有值:

const map = new Map();
foodsList.forEach(item => {
  if (!map.has(item.originCode)) {
    map.set(item.originCode, {
      foodOrigin: item.foodOrigin,
      originCode: item.originCode
    });
  }
});
const filteredFoodsList = Array.from(map.values());

方法2:结合Set与filter

先用Set记录已出现的originCode,再通过filter筛选首次出现的项,最后转换为目标结构:

const seenCodes = new Set();
const filteredFoodsList = foodsList.filter(item => {
  if (!seenCodes.has(item.originCode)) {
    seenCodes.add(item.originCode);
    return true;
  }
  return false;
}).map(({ foodOrigin, originCode }) => ({ foodOrigin, originCode }));

方法3:使用reduce一步完成

用reduce同时实现去重和结构转换,逻辑更紧凑:

const filteredFoodsList = Array.from(
  foodsList.reduce((acc, { foodOrigin, originCode }) => {
    acc.set(originCode, { foodOrigin, originCode });
    return acc;
  }, new Map()).values()
);

这三种方法仅需遍历数组一次,在数据量大时性能优势显著,同时代码更简洁易读,维护成本更低。

内容的提问来源于stack exchange,提问作者a fan of fried rice

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:43:14