Skip to content

Instantly share code, notes, and snippets.

@iigmir
Last active February 2, 2023 17:32
Show Gist options
  • Save iigmir/2759d5455c3098fd3a54805eb5b6b44c to your computer and use it in GitHub Desktop.
Save iigmir/2759d5455c3098fd3a54805eb5b6b44c to your computer and use it in GitHub Desktop.
csv-to-convertor
/**
* @param {Array} keys Array of keys. By definition from [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180), it will be the first line of the file.
* @returns {Function}
*/
const csv_array_to_json = (keys) =>
{
/**
* @param {Array} item Values
* @returns {Object} A JSON format interface.
*/
return item =>
{
const convert_to_json_item = (key, key_id) => ([ key, item[key_id] ]);
const key_values = keys.map(convert_to_json_item);
return Object.fromEntries( key_values );
};
}
/**
* > Each record is located on a separate line, delimited by a line break (CRLF).
* >
* > ~ Definition of the CSV Format, *RFC 4180*.
*/
const extract_source_array = ( input ) =>
{
try {
return input.split( "\n" ).map( item => item.split( "," ) );
} catch (error) {
console.warn( error );
return [];
}
};
/**
* > There maybe an optional header line appearing as the first line
* > of the file with the same format as normal record lines.
* >
* > ~ Definition of the CSV Format, *RFC 4180*.
*/
const extract_keys = source_array => source_array[0] ?? [];
/**
* CSV values.
* @param {Array} source_array
* @returns {Array} Values
*/
const extract_values = source_array => source_array.slice( 1 ) ?? [];
/**
* Convert CSV to JSON.
* @see [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180)
* @param {String} input A CSV string.
* @returns {Array} A JSON object format of CSV.
*/
const csv_convertor = (input = "") =>
{
const source_array = extract_source_array(input);
const keys = extract_keys(source_array);
const values = extract_values(source_array);
return values.map(csv_array_to_json(keys));
};
export default csv_convertor;
/**
* @param {Array} keys Array of keys. By definition from [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180), it will be the first line of the file.
* @returns {Function}
*/
function csv_array_to_json(keys)
{
/**
* @param {Array} item Values
* @returns {Object} A JSON format interface.
*/
const main = item =>
{
const convert_to_json_item = (key, key_id) => ([ key, item[key_id] ]);
return Object.fromEntries( keys.map(convert_to_json_item) );
};
return main;
}
class CsvArray
{
/**
* @see [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180)
* @param {String} source A CSV string.
*/
constructor(source = "")
{
this.source = source;
}
/**
* > Each record is located on a separate line, delimited by a line break (CRLF).
* >
* > ~ Definition of the CSV Format, *RFC 4180*.
*/
get source_array()
{
if( typeof( this.source ) !== "string" )
{
return [];
}
try {
const extracted_row = this.source.split("\n");
const extract_col = item => item.split(",");
return extracted_row.map( extract_col );
} catch (error) {
console.warn( error );
return [];
}
}
/**
* > There maybe an optional header line appearing as the first line
* > of the file with the same format as normal record lines.
* >
* > ~ Definition of the CSV Format, *RFC 4180*.
*/
get keys()
{
return this.source_array[0] ?? [];
}
/**
* CSV values.
* @returns {Array} Values
*/
get values()
{
return this.source_array.slice( 1 ) ?? [];
}
/**
* The JSON item array.
*/
get json_array()
{
return this.values.map( csv_array_to_json( this.keys ) );
}
}
/**
* Convert CSV to JSON.
* @see [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180)
* @param {String} input A CSV string.
* @returns {Array} A JSON object format of CSV.
*/
const csv_convertor = (input = "") => (new CsvArray( input )).json_array;
export default csv_convertor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment