如何在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
相关产品推荐
相关产品推荐

