如何在JavaScript中扁平化嵌套对象数组以适配表格展示?
问题
我通过API调用获取了如下JSON数据:
{ "name": "Ethereum 2.0", "symbol": "ETH", "slug": "ethereum-2-0", "meta": { "start": "2022-08-03T02:43:56Z", "startTimestamp": 1659494636000000000, "end": "2022-08-04T02:43:56Z", "endTimestamp": 1659581036000000000 }, "data": [{ "timestamp": 1659579311, "totalStaked": 10.795673641155977, "engagedBalance": 13151223, "inflation": 0.49479127486939656, "rewardOptions": [{ "Name": "Run a Validator", "Reward": 4.583236686436322, "AdjustedReward": 4.068315740250017 }, { "Name": "Validator-as-a-Service", "Reward": 3.7811702663099656, "AdjustedReward": 3.2701983354060715 }, { "Name": "Exchange Staking", "Reward": 3.899917762276725, "AdjustedReward": 3.388361171967369 }] }, { "timestamp": 1659572709, "totalStaked": 10.795673641155977, "engagedBalance": 13151223, "inflation": 0.49479127486939656, "rewardOptions": [{ "Name": "Run a Validator", "Reward": 4.583236686436322, "AdjustedReward": 4.068315740250017 }, { "Name": "Validator-as-a-Service", "Reward": 3.7811702663099656, "AdjustedReward": 3.2701983354060715 }, { "Name": "Exchange Staking", "Reward": 3.899917762276725, "AdjustedReward": 3.388361171967369 }] } ] }
我需要在JavaScript中扁平化其中的data数组,得到如下预期结果:
[{ "timestamp": 1659579311, "totalStaked": 10.795673641155977, "engagedBalance": 13151223, "inflation": 0.49479127486939656, "rewardOptions[0].Name": "Run a Validator", "rewardOptions[0].Reward": 4.583236686436322, "rewardOptions[0].AdjustedReward": 4.068315740250017, "rewardOptions[1].Name": "Validator-as-a-Service", "rewardOptions[1].Reward": 3.7811702663099656, "rewardOptions[1].AdjustedReward": 3.2701983354060715, "rewardOptions[2].Name": "Exchange Staking", "rewardOptions[2].Reward": 3.899917762276725, "rewardOptions[2].AdjustedReward": 3.388361171967369 },{ "timestamp": 1659572709, "totalStaked": 10.795673641155977, "engagedBalance": 13151223, "inflation": 0.49479127486939656, "rewardOptions[0].Name": "Run a Validator", "rewardOptions[0].Reward": 4.583236686436322, "rewardOptions[0].AdjustedReward": 4.068315740250017, "rewardOptions[1].Name": "Validator-as-a-Service", "rewardOptions[1].Reward": 3.7811702663099656, "rewardOptions[1].AdjustedReward": 3.2701983354060715, "rewardOptions[2].Name": "Exchange Staking", "rewardOptions[2].Reward": 3.899917762276725, "rewardOptions[2].AdjustedReward": 3.388361171967369 }]
我尝试了.map、.flat、.forEach等方法,还有Stack Overflow上的30余种JSON扁平化方案,都没得到预期效果——要么只扁平化了data里的前4个键,保留rewardOptions为对象数组,要么生成的结果不符合需求。因为数据要用于表格展示,最终必须是对象数组才能正常显示。以下是我最接近可行的代码:
var data = {{ querysubmit.data.data }} function flatten(array) { var result = []; array.forEach(function iter(o) { var temp = {}, keys = Object.keys(o); if (keys.length > 1) { keys.forEach(function (k) { if (k !== 'rewardOptions') { temp[k] = o[k]; } }); temp.rewardType1 = o.rewardOptions[0].Name; temp.rewardRate1 = o.rewardOptions[0].Reward; temp.adjustedRewardRate1 = o.rewardOptions[0].AdjustedReward; temp.rewardType2 = o.rewardOptions[1].Name; temp.rewardRate2 = o.rewardOptions[1].Reward; temp.adjustedRewardRate2 = o.rewardOptions[1].AdjustedReward; temp.rewardType3 = o.rewardOptions[2].Name; temp.rewardRate3 = o.rewardOptions[2].Reward; temp.adjustedRewardRate3 = o.rewardOptions[2].AdjustedReward; result.push(temp); } Array.isArray(o.data) && o.temp.forEach(iter); }); return result; } return flatten(data)
解决方案
可以通过遍历每个data项,先复制非rewardOptions的字段,再遍历rewardOptions数组,按照rewardOptions[index].key的格式生成新的键值对,最终组合成目标对象。这种方式既灵活又能准确匹配预期格式:
// 假设apiData是你获取的完整JSON数据 const apiData = { /* 你的API返回数据 */ }; // 扁平化data数组的函数 function flattenData(dataArray) { return dataArray.map(item => { // 先复制除了rewardOptions之外的所有字段 const flattenedItem = {...item}; // 删除原有的rewardOptions数组 delete flattenedItem.rewardOptions; // 遍历rewardOptions数组,生成指定格式的键值对 item.rewardOptions.forEach((option, index) => { Object.keys(option).forEach(key => { flattenedItem[`rewardOptions[${index}].${key}`] = option[key]; }); }); return flattenedItem; }); } // 调用函数获取结果 const flattenedResult = flattenData(apiData.data); console.log(flattenedResult);
代码说明
- 使用
.map遍历data数组,每个项生成一个新的扁平化对象 - 用扩展运算符
...复制当前项的所有字段,然后删除rewardOptions属性 - 嵌套遍历
rewardOptions数组和每个option的键,按照rewardOptions[index].key的格式添加到新对象中 - 返回处理后的对象数组,完全符合表格展示的结构要求
这个方案不需要硬编码rewardOptions的索引和键名,即使后续rewardOptions的数量或字段有变化,代码也能自动适配,比你之前的硬编码版本更健壮。
内容的提问来源于stack exchange,提问作者Nathan Workman
相关产品推荐
相关产品推荐

