You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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);

代码说明

  1. 使用.map遍历data数组,每个项生成一个新的扁平化对象
  2. 用扩展运算符...复制当前项的所有字段,然后删除rewardOptions属性
  3. 嵌套遍历rewardOptions数组和每个option的键,按照rewardOptions[index].key的格式添加到新对象中
  4. 返回处理后的对象数组,完全符合表格展示的结构要求

这个方案不需要硬编码rewardOptions的索引和键名,即使后续rewardOptions的数量或字段有变化,代码也能自动适配,比你之前的硬编码版本更健壮。

内容的提问来源于stack exchange,提问作者Nathan Workman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 05:45:40