Last active
September 14, 2021 17:27
-
-
Save T99/effc9a7f66fd8ceb23352f9a0779d319 to your computer and use it in GitHub Desktop.
Convert JSON data to CSV data.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Created by Trevor Sears <[email protected]> (https://trevorsears.com/). | |
* 12:43 PM -- September 14th, 2021 | |
*/ | |
/** | |
* Returns all of the unique properties found in any of the objects within the given array. | |
* | |
* @param {T[]} jsonArray The array of objects over which to build a list of unique properties. | |
* @returns {Array<keyof T>} An array containing all of the unique properties found in any of the objects within the | |
* given array. | |
*/ | |
function getAllUniqueProps<T>(jsonArray: T[]): Array<keyof T> { | |
let props: Set<keyof T> = new Set(); | |
for (let json of jsonArray) { | |
for (let prop of Object.getOwnPropertyNames(json)) { | |
props.add(prop as keyof T); | |
} | |
} | |
return [...props]; | |
} | |
/** | |
* Returns a 'cleaned' string representation of the input value. | |
* | |
* This is the default 'cleaner' function used to sanitize/clean CSV data for the `jsonToCSV` function. | |
* | |
* @param {any} value The value to 'clean'. | |
* @param {string} separator The separator string being used in the relevant CSV data. | |
* @returns {string} A 'cleaned' version of the input value. | |
*/ | |
function cleanCSVData(value: any, separator: string): string { | |
if (value === true) return "1"; | |
else if (value === false) return "0"; | |
if (typeof value === "string" && value.includes(separator)) return `"${value}"`; | |
return value; | |
} | |
/** | |
* Converts a JSON array to a CSV-style string, returning the result. | |
* | |
* @param {T[]} jsonArray The array of objects from which to source the data for the CSV string result. | |
* @param {Array<keyof T>} fields An optional array of strings that will be used as the fields of the resulting CSV. | |
* @param {string} separator The string to use to separate cells in the resulting data. | |
* @param {(value: string) => string} cleaner An optional callback that will be applied to every value (cell) before | |
* being used in the output string. | |
* @returns {string} A string representation of the generated CSV data. | |
*/ | |
export function jsonToCSV<T>(jsonArray: T[], | |
fields: Array<keyof T> = getAllUniqueProps(jsonArray), | |
separator: string = ",", | |
cleaner: (value: any, separator: string) => string = cleanCSVData): string { | |
let result: string = ""; | |
result += fields.join(separator); | |
for (let json of jsonArray) { | |
let values: string[] = fields.map((property: keyof T): string => cleaner(json[property], separator)); | |
result += `\n${values.join(separator)}`; | |
} | |
return result; | |
} | |
// Example usage: | |
console.log(jsonToCSV([ | |
{ | |
id: 1, | |
name: "John" | |
}, | |
{ | |
id: 2, | |
name: "Jess" | |
}, | |
{ | |
id: 3, | |
name: "Junior" | |
} | |
])); | |
/* id,name | |
* 1,John | |
* 2,Jess | |
* 3,Junior | |
*/ | |
console.log(jsonToCSV([ | |
{ | |
id: 1, | |
name: "John", | |
email: "[email protected]" | |
}, | |
{ | |
id: 2, | |
name: "Jess", | |
phone: "(123) 456 - 7890" | |
}, | |
{ | |
id: 3, | |
name: "Junior", | |
fax: "no one uses fax anymore" | |
} | |
], undefined, "|")); | |
/* id|name|email|phone|fax | |
* 1|John|[email protected]|| | |
* 2|Jess||(123) 456 - 7890| | |
* 3|Junior|||no one uses fax anymore | |
*/ | |
console.log(jsonToCSV([ | |
{ | |
id: 1, | |
name: "John" | |
}, | |
{ | |
id: 2, | |
name: "Jess" | |
}, | |
{ | |
id: 3, | |
name: "Junior" | |
} | |
], ["fields", "that", "don't", "exist"])); | |
/* fields,that,don't,exist | |
* ,,, | |
* ,,, | |
* ,,, | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment