求JavaScript中按domain聚合对象数组的更简洁实现方案
按Domain分组数组的优化实现方案
原始数据
let data = [ { name: 'Alex', domain: 'google.com' }, { name: 'Bob', domain: 'google.com' }, { name: 'Garby', domain: 'facebook.com' }, { name: 'Stones', domain: 'facebook.com' }, { name: 'Tenz', domain: 'linkedin.com' }, ];
需求
将上述数组转换为按domain分组的结构,每个分组包含domain字段及对应name组成的accounts数组,期望输出:
[ {"domain":"google.com","accounts":["Alex","Bob"]}, {"domain":"facebook.com","accounts":["Garby","Stones"]}, {"domain":"linkedin.com","accounts":["Tenz"]} ]
现有实现
let arr = []; for (let i = 0; i < data.length; i++) { let fIndex = arr.findIndex((item) => item.domain === data[i].domain); if (fIndex > -1) { arr[fIndex].accounts.push(data[i].name); } else { arr.push({ domain: data[i].domain, accounts: [data[i].name], }); } }
更简洁的优化方案
方案一:使用Array.reduce()构建映射后转数组
这是最常用的紧凑实现方式:
const result = Object.values(data.reduce((acc, { name, domain }) => { acc[domain] ??= { domain, accounts: [] }; // 逻辑空赋值简化判断 acc[domain].accounts.push(name); return acc; }, {}));
说明:通过reduce先构建以domain为键的映射对象,每个键对应目标分组结构,最后用Object.values提取对象的值组成数组,直接得到期望格式。
方案二:使用Map结构分组(保留插入顺序)
如果需要严格保留原始数据中domain的出现顺序,Map会比普通对象更可靠:
const domainMap = new Map(); data.forEach(({ name, domain }) => { if (!domainMap.has(domain)) { domainMap.set(domain, { domain, accounts: [] }); } domainMap.get(domain).accounts.push(name); }); const result = Array.from(domainMap.values());
说明:Map会维护键的插入顺序,遍历数据时更新Map中的分组,最后通过Array.from将Map的值转为数组。
内容的提问来源于stack exchange,提问作者swamy Reddy
相关产品推荐
相关产品推荐

