'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