[英]JavaScript - Array and Nested Objects
I have an API call that returns the following JSON:我有一个 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
}]
}
]
}
I am trying to flatten the "data" array in Javascript to create the following outcome:我正在尝试展平 Javascript 中的“数据”数组以创建以下结果:
[{
"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
}]
I have tried every.map, .flat, .forEach variety I can find, as well as about 30 different solutions I've found on Stack Overflow to flatten JSON responses (over the past 6 hours), but they'll either flatten the first 4 "data" keys and leave "rewardOptions" as an array of objects or create some other outcome other than what I'm wanting to achieve.我已经尝试过每一个。map、.flat、.forEach 品种,以及我在 Stack Overflow 上找到的大约 30 种不同的解决方案,以使 JSON 响应变平(过去 6 小时内),但它们要么变平前 4 个“数据”键并将“rewardOptions”保留为对象数组,或者创建一些其他结果,而不是我想要实现的结果。 The data is going to be displayed in a table, so I need the final result to be an array of objects so everything displays properly.数据将显示在表格中,所以我需要最终结果是一个对象数组,以便所有内容都能正确显示。 Any help to get me unstuck would be greatly appreciated.任何帮助我摆脱困境的帮助将不胜感激。
Update 1:更新1:
Here's the code for the closest-to-a-working version I had:这是我拥有的最接近工作版本的代码:
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)
}
So for every entry in myObject.data
, you should make a new object, and recursively add values to that new object.因此,对于myObject.data
中的每个条目,您应该创建一个新的 object,并递归地将值添加到新的 object 中。
let myObject = {
"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
}]
}
]
}
function recursiveAddProp(sourceObj, targetObj, keyPrefix) {
if (Array.isArray(sourceObj)) {
for (let i = 0; i < sourceObj.length; i++) {
recursiveAddProp(sourceObj[i], targetObj, keyPrefix + `[${i}]`);
}
} else if (typeof sourceObj === 'object' && sourceObj !== null) {
for (let key in sourceObj) {
recursiveAddProp(sourceObj[key], targetObj, keyPrefix === '' ? key : keyPrefix + '.' + key)
}
} else {
targetObj[keyPrefix] = sourceObj;
}
}
const flattener = (data_entry) => {
let newObj = {}
recursiveAddProp(data_entry, newObj, '')
return newObj;
}
let flattenedObject = myObject.data.map(flattener);
console.log(JSON.stringify(flattenedObject))
Beautified output:美化 output:
[{
"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
}]
If this is just a case, you can make your algorithm for the flatting array.如果这只是一种情况,您可以为扁平数组制作算法。
Here is one way to make that using loops.这是使用循环实现的一种方法。
const arr = { "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 }] } ] } let data = arr.data let res = [] for(let i = 0; i < data.length; i++){ const objKeys = Object.keys(data[i]); let obj = {} for (let j = 0; j < objKeys.length; j++){ if(Array.isArray(data[i][objKeys[j]])){ flatArray(data[i][objKeys[j]], objKeys[j], obj) } else { const key = objKeys[j] obj[key] = data[i][objKeys[j]] } } res.push(obj) } function flatArray(arr, parentKey, res){ for (let j = 0; j < arr.length; j++){ const objKeys = Object.keys(arr[j]); for(let i = 0; i < objKeys.length; i++){ const key = `${parentKey}[${j}].${objKeys[i]}` res[key] = arr[j][objKeys[i]] } } return res } console.log(res)
NOTE: " this solution will not work in case of different level nested arrays "注意:“此解决方案不适用于不同级别的嵌套 arrays ”
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.