如何在JavaScript中按城市及stadium/arena多层分组对象数组?
实现先按city再按stadium/arena的多层分组
原始数据
const data = [ { "countries": ["France", "USA", "Canada"], "city": "Paris", "stadium": "Parce de france" }, { "countries": ["France", "Itlay", "Spain"], "city": "Roma", "arena": "La cigal" }, { "countries": ["France"], "city": "Roma", "stadium": "Olymico" }, { "countries": ["France"], "city": "Paris", "arena": "Velodrome" }, ]
期望输出
[ { "city": "Paris", "arena": [ { "value":"Velodrome", "countries": ["France"] } ], "stadium": [ { "value":"Parce de france", "countries": ["France", "USA", "Canada"]} ] }, { "city": "Roma", "arena": [ { "value":"La cigal", "countries": ["France", "Itlay", "Spain"] } ], "stadium": [ { "value":"Olymico", "countries": ["France"] } ] } ]
现有代码(仅按city分组)
let group = function(array, key) { return array.reduce(function(result, item) { (result[item[key]] = result[item[key]] || []).push(item); return result; }, {}); };
解决方案:扩展reduce实现多层分组
可以直接在reduce中完成两层分组逻辑,先按city聚合,再针对每个city下的项区分stadium或arena类型,整理成目标结构:
const groupByCityAndVenue = (data) => { const cityGroups = data.reduce((acc, item) => { const city = item.city; // 初始化当前城市的分组结构 if (!acc[city]) { acc[city] = { city: city, arena: [], stadium: [] }; } // 根据字段类型整理数据 if (item.stadium) { acc[city].stadium.push({ value: item.stadium, countries: item.countries }); } else if (item.arena) { acc[city].arena.push({ value: item.arena, countries: item.countries }); } return acc; }, {}); // 将对象转换为数组格式 return Object.values(cityGroups); }; // 调用示例 const result = groupByCityAndVenue(data); console.log(result);
逻辑说明
- 用空对象
cityGroups存储每个城市的分组数据 - 遍历原始数组时:
- 若当前城市未在
cityGroups中,创建包含city字段、空arena和stadium数组的初始结构 - 根据当前项存在的
stadium或arena字段,将整理好的value和countries对象推入对应数组
- 若当前城市未在
- 最后用
Object.values()将对象转为数组,得到符合期望的输出格式
内容的提问来源于stack exchange,提问作者mzaxhmars
相关产品推荐
相关产品推荐

