Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@select
Last active December 19, 2022 18:17
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save select/0e2aa49b98ea81db7c615e6560497c41 to your computer and use it in GitHub Desktop.
Save select/0e2aa49b98ea81db7c615e6560497c41 to your computer and use it in GitHub Desktop.
Convert an Array of non uniform Objects to a CSV string with JavaScript
function getKeys(obj, prefix = '') {
if (typeof obj === 'undefined' || obj === null) return [];
return [
...Object.keys(obj).map(key => `${prefix}${key}`),
...Object.entries(obj).reduce((acc, [key, value]) => {
if (typeof value === 'object') return [...acc, ...getKeys(value, `${prefix}${key}.`)];
return acc;
}, []),
];
}
function flatObject(obj, prefix = '') {
if (typeof obj === 'undefined' || obj === null) return {};
return Object.entries(obj).reduce((acc, [key, value]) => {
if (typeof value === 'object') return { ...acc, ...flatObject(value, `${prefix}${key}.`) };
return { ...acc, [`${prefix}${key}`]: value };
}, {});
}
function escapeCsvValue(cell) {
if (cell.replace(/ /g, '').match(/[\s,"]/)) {
return '"' + cell.replace(/"/g, '""') + '"';
}
return cell;
}
function objectsToCsv(arrayOfObjects) {
// collect all available keys
const keys = new Set(arrayOfObjects.reduce((acc, item) => [...acc, ...getKeys(item)], []));
// for each object create all keys
const values = arrayOfObjects.map(item => {
const fo = flatObject(item);
const val = Array.from(keys).map((key: string) => (key in fo ? escapeCsvValue(`${fo[key]}`) : ''));
return val.join(',');
});
return `${Array.from(keys).join(',')}\n${values.join('\n')}`;
}
@garygrubb
Copy link

Wonderful. Thanks for the code.

@clrko
Copy link

clrko commented Dec 7, 2020

Great!! Thanks a lot!

@jamalhassouni
Copy link

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment