Reputation: 481
I currently use this code to reformat my json into the format I want:
let input = {
"Apples": {
"Apples_pos1": 501.82,
"Apples_pos2": 502.61,
"Apples_pos3": 502.61,
"Apples": 502.16,
}
};
let output = Object.keys(input).reduce((acc, outerKey) => {
for (let [key, value] of Object.entries(input[outerKey])) {
acc.push([outerKey, value, key.split('_')[1] || key]);
}
return acc;
}, []);
console.log(output);
[
[
"Apples",
501.82,
"pos1"
],
[
"Apples",
502.61,
"pos2"
],
[
"Apples",
502.61,
"pos3"
],
[
"Apples",
502.16,
"Apples"
]
]
If my input instead looked like this:
let second_input = {
"Apples": {
"11-26-19": {
"Apples_pos1": 501.82,
"Apples_pos2": 502.61,
"Apples_pos3": 502.61,
"Apples": 502.16,
}
}
};
And this is my desired output:
[
[
"Apples",
501.82,
"pos1",
"11-26-19"
],
[
"Apples",
502.61,
"pos2",
"11-26-19"
],
[
"Apples",
502.61,
"pos3",
"11-26-19"
],
[
"Apples",
502.16,
"Apples",
"11-26-19"
]
]
How could I edit my old code to be able to produce this desired output?
Thanks.
Upvotes: 1
Views: 79
Reputation: 7299
Here you go
let input = {
"Apples": {
"11-26-19": {
"Apples_pos1": 501.82,
"Apples_pos2": 502.61,
"Apples_pos3": 502.61,
"Apples": 502.16,
}
}
};
let output = [];
Object.keys(input).map(key1 => {
Object.keys(input[key1]).map(key2 => {
for(let key3 in input[key1][key2]) {
output.push([key1, input[key1][key2][key3], key3.split('_')[1] || key3.split('_')[0], key2]);
}
});
})
console.log(output);
Upvotes: 1
Reputation: 20851
You need to go one more layer deep, because you're now iterating over a subarray.
Explanation of Approach: I kept the style of code you had used, by doing another for (let [key, value] of Object.entries(...))
call -- this way, your code continues to resemble what it was before. If you need to go another layer deep, just follow the same procedure again, and knowing what to do should be no problem. In this case, continuity of code is a good thing! In the code, notice our new vars, subkey
and subvalue
...
let output = Object.keys(input).reduce((acc, outerKey) => {
for (let [key, value] of Object.entries(input[outerKey])) {
for (let [subkey, subvalue] of Object.entries(input[outerKey][key])) {
var goodsubkey = subkey.replace(/^outerKey + '_'/, '');
acc.push([outerKey, subvalue, goodsubkey, key]);
}
}
return acc;
}, []);
Also, your arr.split(_)[1]
call was a bit unclear, and it certainly won't work on increasingly, longer keys. So, I replaced this naturally with arr.replace(/^outerKey + '_'/, '');
, which will have that forward compatibility. For instance, this key would break on your old code: Apples_pos1_pos2
, etc..
Made a fully, working demo. Output...
[["Apples", 501.82, "pos1", "11-26-19"], ["Apples", 502.61, "pos2", "11-26-19"], ["Apples", 502.61, "pos3", "11-26-19"], ["Apples", 502.16, "Apples", "11-26-19"]]
Upvotes: 1
Reputation: 515
My try for this task, just modified the script a bit:
let input = {
"Apples": {
"11-26-19": {
"Apples_pos1": 501.82,
"Apples_pos2": 502.61,
"Apples_pos3": 502.61,
"Apples": 502.16,
}
}
};
let output = Object.keys(input).reduce((acc, outerKey) => {
Object.entries(input[outerKey]).forEach(([date, item]) => {
for (let [key, value] of Object.entries(item)) {
acc.push([outerKey, value, key.split('_')[1] || key, date]);
}
});
return acc;
}, []);
console.log(output);
Output:
[
[
"Apples",
501.82,
"pos1",
"11-26-19"
],
[
"Apples",
502.61,
"pos2",
"11-26-19"
],
[
"Apples",
502.61,
"pos3",
"11-26-19"
],
[
"Apples",
502.16,
"Apples",
"11-26-19"
]
]
Upvotes: 1