I'm building an API and getting the data from my database in the given format.
There won't be repetitions like {country: 'India', count: 2, status: 'Active'},{country: 'India', count: 1, status: 'Active'}
const dataFromDB = [
{country: 'India', count: 2, status: 'Active'}, {country: 'USA', count: 3, status: 'Recovered'},
{country: 'India', count: 2, status: 'Recovered'}, {country: 'Russia', count: 1, status: 'Active'},
{country: 'India', count: 1, status: 'Dead'}, {country: 'Brazil', count: 1, status: 'Active'},
{country: 'Canada', count: 1, status: 'Dead'}, {country: 'USA', count: 1, status: 'Active'}
]
But I want to convert my data into a different format before sending it out.
const formatIWant = {
Brazil: {
active: 1,
dead: 0,
recovered: 0
},
Canada: {
active: 0,
dead: 1,
recovered: 0
},
India: {
active: 2,
dead: 1,
recovered: 2
},
Russia: {
active: 1,
dead: 0,
recovered: 0
},
USA: {
active: 1,
dead: 0,
recovered: 3
}
}
How do I tackle this problem.
CodePudding user response:
To convert the data into your desired format, we can create an object, formatIWant
, then iterate through dataFromDB
, updating that object with the relevant data as we go.
Here's a simple implementation that will yield the result you are looking for.
const dataFromDB = [
{country: 'India', count: 2, status: 'Active'},
{country: 'USA', count: 3, status: 'Recovered'},
{country: 'India', count: 2, status: 'Recovered'},
{country: 'Russia', count: 1, status: 'Active'},
{country: 'India', count: 1, status: 'Dead'},
{country: 'Brazil', count: 1, status: 'Active'},
{country: 'Canada', count: 1, status: 'Dead'},
{country: 'USA', count: 1, status: 'Active'}
]
const formatIWant = {};
for(let i=0; i<dataFromDB.length; i ){
let country = dataFromDB[i].country;
let count = dataFromDB[i].count;
let status = dataFromDB[i].status;
// add entry for country if not found
!formatIWant[country] ? formatIWant[country] = {
active: 0,
dead: 0,
recovered: 0
} : '';
// update country with data
formatIWant[country][status.toLowerCase()] = count;
}
console.log(formatIWant);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can use .reduce()
const dataFromDB = [
{country: 'India', count: 2, status: 'Active'}, {country: 'USA', count: 3, status: 'Recovered'},
{country: 'India', count: 2, status: 'Recovered'}, {country: 'Russia', count: 1, status: 'Active'},
{country: 'India', count: 1, status: 'Dead'}, {country: 'Brazil', count: 1, status: 'Active'},
{country: 'Canada', count: 1, status: 'Dead'}, {country: 'USA', count: 1, status: 'Active'}
];
const defaultStatus = dataFromDB.reduce((acc, {status}) =>
acc.hasOwnProperty(status.toLowerCase()) ?
acc :
{...acc, [status.toLowerCase()]: 0}
, {});
const result = dataFromDB.reduce((acc, value)=> {
const country = value.country.toLowerCase();
const status = value.status.toLowerCase();
const currentTotal = acc?.[country]?.[status] || defaultStatus[status];
return {
...acc,
[country]: {
...defaultStatus,
...acc[country],
[status]: currentTotal value.count
}
}
}, {});
console.log(result);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Just loop thru the array
of plain objects
and create a new object with different keys using each data. This for example
const reformat = (dataFromDB) => {
const formatted = {};
for (const data of dataFromDB) {
formatted[data.country] = {
recovered: 0,
active: 0,
dead: 0,
...formatted[data.country],
[data.status.toLowerCase()]: data.count,
};
}
return formatted;
};
console.log(
reformat([
{ country: 'India', count: 2, status: 'Active' },
{ country: 'USA', count: 3, status: 'Recovered' },
{ country: 'India', count: 2, status: 'Recovered' },
{ country: 'Russia', count: 1, status: 'Active' },
{ country: 'India', count: 1, status: 'Dead' },
{ country: 'Brazil', count: 1, status: 'Active' },
{ country: 'Canada', count: 1, status: 'Dead' },
{ country: 'USA', count: 1, status: 'Active' },
])
);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>