'Produce CSV from JSON object
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
Solution 1:[1]
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'));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | syduki |