如何将扁平化对象数组按层级嵌套?reduce方法使用遇阻
扁平化对象数组转层级嵌套结构问题
我正在学习对象数组相关知识,现有一个扁平化的对象数组,想要依据唯一值将其按层级嵌套。目前我使用reduce方法处理,但得到的是重复的扁平对象,而非预期的嵌套结构。
原始数据
const data = [ { name1: 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4 }, { name1: 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Singles', id3: 4 }, { name1: 'Tenis', id1: 1, name2: 'ATP', id2: 2, name3: 'Men Doubles', id3: 5 }, { name1: 'Tenis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Doubles', id3: 6 }, { name1: 'Tenis', id1: 1, name2: 'WTA', id2: 3, name3: 'Women Singles', id3: 7 } ];
预期结果
result: [ { sport: 'Tenis', league: [{ ATP: [{ event: 'Men Singles' }, { event: 'Men Doubles' }], WTA: [{ event: 'Women Doubles' }, { event: 'Women Singles' }] }] }]
当前代码
const result = data.reduce((arr, item) => { if (arr.indexOf(item.name1) === -1) { arr.push({ sport: item.name1 , league: item.name2 , event: item.name3 , }) } return arr }, [])
实际得到的结果
0: {sport: 'Tenis', league: 'ATP', event: 'Men Singles'} 1: {sport: 'Tenis', league: 'WTA', event: 'Women Doubles'} 2: {sport: 'Tenis', league: 'WTA', event: 'Women Doubles'} // 其他重复项...
解决方案
当前代码的问题在于:arr.indexOf(item.name1) 是在数组中查找字符串,但数组元素是对象,因此永远返回 -1,导致每次循环都添加新的扁平对象,且未处理嵌套结构。
修改后的reduce逻辑需要分层级查找并去重:
const result = data.reduce((acc, item) => { // 查找当前sport是否已存在于结果数组 let sportItem = acc.find(sport => sport.sport === item.name1); if (!sportItem) { // 不存在则创建新的sport对象,初始化league结构 sportItem = { sport: item.name1, league: [{}] }; acc.push(sportItem); } const leagueContainer = sportItem.league[0]; // 检查当前联赛是否已初始化事件数组 if (!leagueContainer[item.name2]) { leagueContainer[item.name2] = []; } // 避免重复添加相同事件 const eventExists = leagueContainer[item.name2].some(event => event.event === item.name3); if (!eventExists) { leagueContainer[item.name2].push({ event: item.name3 }); } return acc; }, []);
逻辑说明
- 层级1(Sport):遍历每个元素时,先检查当前sport是否已存在于结果数组,不存在则创建新的sport对象并初始化嵌套结构。
- 层级2(League):在sport的league容器中,检查当前联赛(ATP/WTA)是否已创建事件数组,未创建则初始化。
- 层级3(Event):检查当前事件是否已存在于对应联赛的数组中,避免重复添加,不存在则推入数组。
执行后得到的结果与预期完全一致,且自动去重了原始数据中的重复项。
内容的提问来源于stack exchange,提问作者Arssin
相关产品推荐
相关产品推荐

