There is a use case whereby data
needs to be transformed into result
for the purpose of displaying the data in the UI in a pivoted format. In result
the numbered keys are the month numbers and their values are the quantity for that month.
const data = [
{ date: '10/1/2021', quantity: 47 },
{ date: '11/1/2021', quantity: 58 },
{ date: '12/1/2021', quantity: 96 },
{ date: '1/1/2022', quantity: 88 },
{ date: '2/1/2022', quantity: 90 },
];
const result = [
{ year: 2021, 10: 47, 11: 58, 12: 96 },
{ year: 2022, 1: 88, 2: 90 }
];
So far I have created intermediate
but don't know how to get that into the final result
format in a concise manner. ES6 solutions are preferred.
const data = [
{ date: '10/1/2021', quantity: 47 },
{ date: '11/1/2021', quantity: 58 },
{ date: '12/1/2021', quantity: 96 },
{ date: '1/1/2022', quantity: 88 },
{ date: '2/1/2022', quantity: 90 },
];
const intermediate = data.map(o => {
// eslint-disable-next-line no-unused-vars
const [month, day, year] = o.date.split('/'); // destructuring assignment
return {
year: year,
[month]: o.quantity
}
});
console.log(intermediate);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Updated: from intermediate
to result
const intermediate = [
{ '10': 47, 'year': '2021' },
{ '11': 58, 'year': '2021' },
{ '12': 96, 'year': '2021' },
{ '1': 88, 'year': '2022' },
{ '2': 90, 'year': '2022' }
]
const yearDataMap = {}
intermediate.forEach(dto => {
const storageObj = {} // temp store object
Object.entries(dto).forEach(([key, value]) => { // destructure object props
if(key === 'year') {
storageObj['year'] = value
}else {
storageObj['month'] = key
storageObj['quantity'] = value
}
})
const {year, month, quantity} = storageObj
if (!yearDataMap[year]){ // if no entries with this year preset it with year record
yearDataMap[year] = { year } // same as = { year: year }
}
yearDataMap[year][month] = quantity
})
const yearsArr = Object.values(yearDataMap)
console.log(yearsArr)
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
From given
to result
:
const data = [
{ date: '10/1/2021', quantity: 47 },
{ date: '11/1/2021', quantity: 58 },
{ date: '12/1/2021', quantity: 96 },
{ date: '1/1/2022', quantity: 88 },
{ date: '2/1/2022', quantity: 90 },
];
const yearDataMap = {} // map to store dates by year
data.forEach(dto => {
const {date, quantity} = dto
const [month, day, year] = date.split('/')
if (!yearDataMap[year]){ // if no entries with this year preset it with year record
yearDataMap[year] = { year } // same as = { year: year }
}
yearDataMap[year][month] = quantity // adding quantity by month
})
const yearDataArr = Object.values(yearDataMap) // get rid of map and get the `result`
console.log(yearDataArr)
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
your approach was not bad. i built on it. the goal was to fill a global object. that was it.
globalObj = {}
data = [
{ date: '10/1/2021', quantity: 47 },
{ date: '11/1/2021', quantity: 58 },
{ date: '12/1/2021', quantity: 96 },
{ date: '1/1/2022', quantity: 88 },
{ date: '2/1/2022', quantity: 90 },
];
data.forEach((o) => {
[month, day, year] = o.date.split('/');
if (!globalObj[year]) {
globalObj[year] = { year }
}
globalObj[year][month] = o.quantity
})
const result = Object.values(globalObj)
console.log(result)
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>