如何用.map()或.reduce()转换对象数组结构,实现源与系统关联反转
如何用
reduce()转换对象数组结构:从“多源对应单系统”到“单源对应多系统” 你需要将原本每个系统对应多个源的数组结构,转换为每个源对应多个系统的结构,reduce()是最适合这个场景的方法(map()更适合一对一的转换,而这里需要聚合分组,所以reduce()更合适)。
输入数据
const inputDoctypes = [ { "Source": [{"Title": "Anchor (WI)"}, {"Title": "Lafayette Savings Bank"}, {"Title": "United Bancorp"}, {"Title": "Old National"}], "System": {"Title": "Nautilus"}, "Title": "Deposit Documents" }, { "Source": [{"Title": "Founders"}], "System": {"Title": "SharePoint"}, "Title": "Deposit Documents" }, { "Source": [{"Title": "Anchor (MN)"}, ], "System": {"Title": "OmniView"}, "Title": "Deposit Documents" }, { "Source": [{"Title": "Old National"}, {"Title": "Anchor (WI)"}, {"Title": "Lafayette Savings Bank"}, {"Title": "United Bancorp"}], "System": {"Title": "CSS (Aperio)"}, "Title": "Deposit Documents" } ];
期望输出
[ { Source: 'Anchor (MN)', System: [{ Title: 'OmniView' }] }, { Source: 'Anchor (WI)', System: [{ Title: 'Nautilus' }, { Title: 'CSS (Aperio)' }] }, { Source: 'Founders', System: [{ Title: 'SharePoint' }] }, { Source: 'Lafayette Savings Bank', System: [{ Title: 'Nautilus' }, { Title: 'CSS (Aperio)' }] }, { Source: 'Old National', System: [{ Title: 'Nautilus' }, { Title: 'CSS (Aperio)' }] }, { Source: 'United Bancorp', System: [{ Title: 'Nautilus' }, { Title: 'CSS (Aperio)' }] } ]
解决方案代码
const inputDoctypes = [/* 你的输入数据 */]; // 使用reduce构建中间聚合对象,键为源名称,值为对应的源-系统结构 const sourceSystemMap = inputDoctypes.reduce((accumulator, currentItem) => { // 提取当前条目的系统信息 const currentSystem = { Title: currentItem.System.Title }; // 遍历当前条目下的所有源 currentItem.Source.forEach(source => { const sourceTitle = source.Title; // 如果该源已经在聚合对象中,就追加系统;否则新建条目 if (accumulator[sourceTitle]) { accumulator[sourceTitle].System.push(currentSystem); } else { accumulator[sourceTitle] = { Source: sourceTitle, System: [currentSystem] }; } }); return accumulator; }, {}); // 将聚合对象转换为数组,得到最终结果 const desiredOutput = Object.values(sourceSystemMap); console.log(desiredOutput);
关键思路说明
reduce()的作用:它会遍历输入数组的每一项,逐步构建一个中间对象(sourceSystemMap),这个对象的键是源的名称(比如Anchor (WI)),值是包含该源和对应系统数组的对象。- 遍历源列表:对于每个输入条目,我们会遍历它的所有源,把当前条目对应的系统添加到每个源的系统数组中。
- 转换为数组:最后用
Object.values()把中间对象的取值转换为数组,就得到了你想要的结构。
可选优化:避免重复系统
如果你的输入中可能出现同一源重复绑定同一系统的情况,可以在追加系统前做个去重检查:
// 替换原有的push逻辑 if (!accumulator[sourceTitle].System.some(s => s.Title === currentSystem.Title)) { accumulator[sourceTitle].System.push(currentSystem); }
内容的提问来源于stack exchange,提问作者cfoster5
相关产品推荐
相关产品推荐

