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

基于嵌套数组文本分组对象数组:使用reduce重构函数

用reduce重构分组函数是否更优?

我有一个接受三个参数的函数:数据数组、key和部分匹配值。我希望根据每个对象嵌套数组中可能存在的值对结果进行分组。目前我的代码可以正常运行,但想了解是否使用reduce重构会更优。

示例数据数组

const arr = [
  {
    "id": "vghjnbghjkoijhjnmkjhjk",
    "region": "US",
    "tags": ["tag1:bvghjhgh","tag2:bvghjkjnm","tag3:vghjbghj"]
  },
  {
    "id": "cvbhyt56789-mnbvghyu76",
    "region": "US",
    "tags": ["tag1:bvghjhgh"]
  },
  {
    "id": "ghjkjnbhjnbhjkmnhjkmjk",
    "region": "US",
    "tags": ["tag2:bvghjkjnm"]
  },
  {
    "id": "ghjkjnbhjnbhjkmnhjkmjk",
    "region": "US",
    "tags": []
  },
  {
    "id": "bghjkjnbghjkjnhjnbhjhj",
    "region": "CA",
    "tags": ["tag1:bvghjhgh","tag3:vghjbghj"]
  }
];

预期结果

当key为tags、value为tag1时,返回结果如下:

[
  [
    {
      "id": "vghjnbghjkoijhjnmkjhjk",
      "region": "US",
      "tags": ["tag1:bvghjhgh","tag2:bvghjkjnm","tag3:vghjbghj"]
    },
    {
      "id": "cvbhyt56789-mnbvghyu76",
      "region": "US",
      "tags": ["tag1:bvghjhgh"]
    },
    {
      "id": "bghjkjnbghjkjnhjnbhjhj",
      "region": "CA",
      "tags": ["tag1:bvghjhgh","tag3:vghjbghj"]
    }
  ],
  [
      {
        "id": "ghjkjnbhjnbhjkmnhjkmjk",
        "region": "US",
        "tags": ["tag2:bvghjkjnm"]
      },
      {
        "id": "ghjkjnbhjnbhjkmnhjkmjk",
        "region": "US",
        "tags": []
      },
  ]
]

当前实现代码

function groupData(arr, key, value) {
  const grouped = {};
  const remaining = [];

  for (const obj of arr) {
    const index = obj[key].findIndex(elem => elem.includes(value));  
    if (index > -1) {
      const groupByKey = obj[key][index];
      if (grouped.hasOwnProperty(groupByKey)) {
        grouped[groupByKey].push(obj);
      } else {
        grouped[groupByKey] = [obj];
      }
    } else {
      remaining.push(obj);
    }
  }

  return [Object.values(grouped).flat(), remaining]; // 注:原代码里的noMatch应为remaining,此处修正笔误
}

用reduce重构的版本

可以用Array.reduce()把逻辑整合到一个函数调用里,实现更紧凑的函数式风格:

function groupDataWithReduce(arr, key, value) {
  const { grouped, remaining } = arr.reduce((acc, obj) => {
    const matchingTag = obj[key].find(elem => elem.includes(value));
    if (matchingTag) {
      acc.grouped[matchingTag] = [...(acc.grouped[matchingTag] || []), obj];
    } else {
      acc.remaining.push(obj);
    }
    return acc;
  }, { grouped: {}, remaining: [] });

  return [Object.values(grouped).flat(), remaining];
}

两种实现的对比

  • 可读性:原for循环逻辑直白,新手更容易理解和调试;reduce版本更紧凑,但需要熟悉函数式编程风格才能快速理清逻辑。
  • 性能:两者都是O(n)时间复杂度(n为数组长度),每个元素仅遍历一次,性能差异可忽略。
  • 灵活性:reduce把状态管理整合到一个对象中,后续扩展分组规则时修改更方便;for循环则需要维护外部变量。

如果你偏好函数式编程风格、追求代码简洁,reduce重构是不错的选择;如果团队新手较多、需要更直观的调试体验,原有for循环写法也完全没问题——两种方式都能达到预期效果,没有绝对的“更优”,取决于你的场景和团队习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:25:19