I have an array in react like below
[
{
year: 2014
field: "Coal"
value: 100
},
{
year: 2014
field: "power"
value: 200
}, {
year: 2014
field: "oil"
value: 20
},
{
year: 2014
field: "air"
value: 33
}
]
Is there any possible way to convert this array on the basis of a common property. In this it is Year.And get the result like below
{
year: 2014,
coal:100,
power:200
air: 33,
oil: 20
}
CodePudding user response:
you can try something like this:
let arr = [
{year: 2014, field: 'Coal', value: 100 },
{year: 2014, field: 'power', value: 200},
{year: 2014, field: 'oil', value: 20},
{year: 2014, field: 'air', value: 33},
{year: 2015, field: 'Coal', value: 101},
{year: 2015, field: 'power', value: 202},
{year: 2015, field: 'oil', value: 23},
{year: 2015, field: 'air', value: 33}
];
arr = arr.reduce((result, e) => {
(result[e.year] = result[e.year] || {})[e.field] = e.value;
return result;
}, {});
console.log(arr);
CodePudding user response:
Here a solution with a reduce. It's not the cleanest but it works. If you already have something like immer in your project it could be of hlp.
type Energies = 'coal' | 'power' | 'oil' | 'air'
type RawEntry = {
year: number,
field: Energies
value: number
}
type ByYearEntry = {
year: number
[key: string]: number
}
const data2014: RawEntry[] = [
{ year: 2014, field: 'coal', value: 100 },
{ year: 2014, field: 'power', value: 200 },
{ year: 2015, field: 'coal', value: 1000 },
{ year: 2015, field: 'power', value: 2000 },
]
function format(data: RawEntry[]) {
return data.reduce((acc, { year, field, value }) => {
const yearData = acc.find(d => d.year === year)
if (yearData) {
yearData[field] = value
return acc
}
acc.push({ year, [field]: value })
return acc
}, [] as ByYearEntry[])
}
console.log(format(data2014))
PS: Instead of your proposed data structure, you could go for something like
{
2014: {
coal: 100,
power: 100,
},
}
Is it something you could consider? I guess it depends on whaat you want to do with the data after.