I have a JSON Object like so that I am trying to produce a CSV from
{
"football": {
"count": 2109,
"emailed": 0,
"optin": 2109,
},
"tennis": {
"count": 61114,
"emailed": 11111,
"optin": 555,
}
}
However, the fields titles have to be different
What I am after is essentially something like this
Sport, Total, Emails Sent, No Opt Ins,
football, 2109, 0, 2109,
tennis, 61114, 11111, 555
I am tried using packages but can't seem to get it working, as such, then tried doing it myself
const fields = ['Sport', 'Total', 'Emails Sent', 'No Opt Ins'];
I wrapped my JSON in an array so I could use map
try {
const replacer = (key, value) => (value === null ? '' : value);
const csv = [
fields.join(','),
...dataReduced.map((row) => fields.map((fieldName) => JSON.stringify(row[fieldName], replacer)).join(',')),
].join('\r\n');
console.log(csv);
} catch (err) {
console.error(err);
}
Obviously that wont work because the field names do not match the Object names. How can I produce a CSV output in the way described above?
Thanks
Since the row is an object literal, the keys may not necessarily be sorted, so the map here is not enough, there should be a mapper for columns, something like this:
const row = {
"football": {
"count": 2109,
"emailed": 0,
"optin": 2109,
},
"tennis": {
"count": 61114,
"emailed": 11111,
"optin": 555,
}
};
const head = {
football: {id: 0, name: 'Sport'},
count: {id: 1, name: 'Total'},
emailed: {id: 2, name: 'Emails Sent'},
optin: {id: 3, name: 'No Opt Ins'}
};
const csv = [Object.values(head).sort((a, b) => a.id - b.id)
.map(value => value.name).join()];
Object.entries(row).forEach(([key, value]) => {
const line = [key];
Object.entries(value).forEach(([key, value]) => {
line[head[key].id] = value;
});
csv.push(line.join());
});
console.log(csv.join('\n'));