Skip to content

Instantly share code, notes, and snippets.

@adrian154
Created July 25, 2021 21:29
Show Gist options
  • Select an option

  • Save adrian154/17134bddcb7d3ad77aedd44643124004 to your computer and use it in GitHub Desktop.

Select an option

Save adrian154/17134bddcb7d3ad77aedd44643124004 to your computer and use it in GitHub Desktop.
// crude, primitive module for tackling CSVs
// use something better i beg
const parseCSV = (text, delimiter = ",") => {
// extract column headers
const firstNewline = text.indexOf("\n");
const columns = text.slice(0, firstNewline).split(delimiter);
// read
let curPart = "";
let curColumn = 0;
let quote = false, escapeQuote = false;
let curRow = {};
let result = [];
for(let i = firstNewline + 1; i < text.length; i++) {
const char = text[i];
// handle terminators
if(!quote && (char === delimiter || char === '\n')) {
curRow[columns[curColumn]] = curPart;
curPart = "";
curColumn++;
if(char === '\n') {
result.push(curRow);
curRow = {};
curColumn = 0;
}
continue;
}
// handle quotes
if(char === '"') {
if(escapeQuote) {
escapeQuote = false;
} else if(quote && text[i + 1] === '"') {
escapeQuote = true;
continue;
} else {
quote = !quote;
continue;
}
}
curPart += char;
}
return result;
};
const exportCSV = (rows, delimiter = ",") => {
const columns = [];
for(const row of rows) {
for(const col in row) {
if(!columns.includes(col)) {
columns.push(col);
}
}
}
return [columns.join(delimiter), ...rows.map(row => columns.map(col => {
const str = String(row[col] ?? "");
if(str.includes('"') || str.includes(delimiter)) return '"' + str.replace(/"/g, '""') + '"';
return str;
}).join(delimiter))].join("\n");
};
module.exports = {parseCSV, exportCSV};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment