Reputation: 15
I have a nested array of objects like:
const data = {
"rates": {
"2019-09-04": {
"USD": 0.1275393858,
},
"2019-09-05": {
"USD": 0.1275638511,
}, "2019-09-06": {
...
}
All I want is make the array flat, and return the result as:
"rates": {
1:{
"date": "2019-09-04"
"rate": "0.1275393858",
"currency":"USD"
},
} 2:{ ...
I have tried Object.key
but i cannot destruct the 'rates'.
it is what i have tried.
const newData = {
rates: Object.keys(data.rates).map((date, idx) => {
return {
date,
rate: data.rates
}
})
};
Do I have to "double map" the data in order to get what i want?
Upvotes: 1
Views: 2537
Reputation: 13409
There are a lot of ways (as always) like using map
, reduce
or the simple one is to loop over the rates
entries and recreate another object with the structure you want.
It should look something like this:
const obj = {
"rates": {
"2019-09-04": {
"USD": 0.1275393858,
},
"2019-09-05": {
"USD": 0.1275638511,
}
}
}
const transformedObj = {rates: {}}
let i = 0
for (let [key, value] of Object.entries(obj.rates)) {
transformedObj.rates[i++] = {
date: key,
rate: Object.values(value)[0],
currency: Object.keys(value)[0]
}
}
console.log(transformedObj)
Update:
If you don't want to use the index then do like this:
const obj = {
"rates": {
"2019-09-04": {
"USD": 0.1275393858,
},
"2019-09-05": {
"USD": 0.1275638511,
}
}
}
const transformedObj = {rates: {}}
for (let [key, value] of Object.entries(obj.rates)) {
transformedObj.rates[key] = {
date: key,
rate: Object.values(value)[0],
currency: Object.keys(value)[0]
}
}
console.log(transformedObj)
Upvotes: 1
Reputation: 66817
The "double map" may not be sufficient enough. Though the idea is valid, your problem consists of "getting the properties of an object" twice, while also assigning its right values to it.
A solution using two maps could look like this:
const dates = Object.keys(data.rates);
const results = dates.map((date) => {
const currencies = Object.keys(data.rates[date]);
return currencies.map(currency => {
return {
date: date,
rate: data.rates[date][currency],
currency: currency,
};
});
})
Though this will be an array of arrays! This makes sense if you assume you have a rate with two currencies:
"2019-09-04": {
"USD": 0.1275393858,
"EUR": 1.47455,
},
This alone yields one array with two elements. An each other rate may generate a dynamic amount of objects in their own array.
You need to flatten that array of arrays. Alas, Array.prototype.flat
and Array.prototype.flatMap
is not widely supported.
So you may be better off using a library like lodash.
So with that being said you get your wanted result via:
_.flatten(results), null, 4)
Lodash also supports a flatMap, then a solution could be written like:
import * as _ from "lodash";
const data = {
"rates": {
"2019-09-04": {
"USD": 0.1275393858,
"EUR": 1.47455,
},
"2019-09-05": {
"USD": 0.1275638511,
},
},
};
const dates = Object.keys(data.rates);
const results = _.flatMap(dates, (date) => {
const currencies = Object.keys(data.rates[date]);
return currencies.map(currency => {
return {
date: date,
rate: data.rates[date][currency],
currency: currency,
};
});
});
console.log(JSON.stringify(results, null, 4));
Will print:
[
{
"date": "2019-09-04",
"rate": 0.1275393858,
"currency": "USD"
},
{
"date": "2019-09-04",
"rate": 1.47455,
"currency": "EUR"
},
{
"date": "2019-09-05",
"rate": 0.1275638511,
"currency": "USD"
}
]
Upvotes: 0