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

如何在JavaScript中按国家和系列分组对象并返回新结构

JavaScript 多级分组:按国家和系列分组对象数组

需求说明

需要将包含硬币信息的对象数组,先按country字段分组,再在每个国家分组下按series字段二次分组,最终得到嵌套层级的结构。

示例输入

[
  {
    "id": "AD012014001R",
    "country": "AD",
    "series": 1,
    "issue_year": 2014
  },
  {
    "id": "AD012014002R",
    "country": "AD",
    "series": 1,
    "issue_year": 2014
  },
  {
    "id": "AT012002002R",
    "country": "AT",
    "series": 1,
    "issue_year": 2002
  },
  {
    "id": "BE011999100R",
    "country": "BE",
    "series": 1,
    "issue_year": 1999
  },
  {
    "id": "BE011999200R",
    "country": "BE",
    "series": 1,
    "issue_year": 1999
  },
  {
    "id": "BE022008001R",
    "country": "BE",
    "series": 2,
    "issue_year": 2008
  }
]

期望输出

[
  {
    "country": "AD",
    "series": [
      {
        "series": 1,
        "coins": [
          {
            "id": "AD012014001R",
            "country": "AD",
            "series": 1,
            "issue_year": 2014
          },
          {
            "id": "AD012014002R",
            "country": "AD",
            "series": 1,
            "issue_year": 2014
          }
        ]
      }
    ]
  },
  {
    "country": "AT",
    "series": [
      {
        "series": 1,
        "coins": [
          {
            "id": "AT012002002R",
            "country": "AT",
            "series": 1,
            "issue_year": 2002
          }
        ]
      }
    ]
  },
  {
    "country": "BE",
    "series": [
      {
        "series": 1,
        "coins": [
          {
            "id": "BE011999100R",
            "country": "BE",
            "series": 1,
            "issue_year": 1999
          },
          {
            "id": "BE011999200R",
            "country": "BE",
            "series": 1,
            "issue_year": 1999
          }
        ]
      },
      {
        "series": 2,
        "coins": [
          {
            "id": "BE022008001R",
            "country": "BE",
            "series": 2,
            "issue_year": 2008
          }
        ]
      }
    ]
  }
]

实现方案

基础版本(逻辑直观)

使用reduce遍历数组,逐层构建分组结构:

const groupCoins = (coins) => {
  // 按country构建临时分组对象
  const countryGroups = coins.reduce((acc, coin) => {
    const { country, series } = coin;
    
    // 初始化当前国家的分组结构
    if (!acc[country]) {
      acc[country] = { country, series: [] };
    }
    
    // 查找当前国家下对应的series分组
    const targetSeries = acc[country].series.find(item => item.series === series);
    if (targetSeries) {
      // 已存在则追加硬币
      targetSeries.coins.push(coin);
    } else {
      // 不存在则新建series分组
      acc[country].series.push({ series, coins: [coin] });
    }
    
    return acc;
  }, {});

  // 将对象转为数组,得到最终结果
  return Object.values(countryGroups);
};

// 测试调用
const input = [/* 示例输入数组 */];
const output = groupCoins(input);
console.log(JSON.stringify(output, null, 2));

高性能版本(适合大数据量)

通过嵌套对象存储分组,避免频繁的数组查找操作,提升处理效率:

const groupCoins = (coins) => {
  // 先按country和series构建双层对象结构
  const tempGroups = coins.reduce((acc, coin) => {
    const { country, series } = coin;
    
    // 初始化国家层级
    if (!acc[country]) {
      acc[country] = { country, series: {} };
    }
    
    // 初始化系列层级
    if (!acc[country].series[series]) {
      acc[country].series[series] = { series, coins: [] };
    }
    
    // 添加硬币到对应分组
    acc[country].series[series].coins.push(coin);
    return acc;
  }, {});

  // 将系列的对象转为数组,得到目标结构
  return Object.values(tempGroups).map(countryItem => {
    countryItem.series = Object.values(countryItem.series);
    return countryItem;
  });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:35:08