Skip to content

Instantly share code, notes, and snippets.

@benergize
Last active June 12, 2020 18:13
Show Gist options
  • Save benergize/c558edb2edd1b9d4423e8f7a6ada8507 to your computer and use it in GitHub Desktop.
Save benergize/c558edb2edd1b9d4423e8f7a6ada8507 to your computer and use it in GitHub Desktop.
Simple function to convert a CSV to a JS object/JSON.
function csvToJSON(csv, textDelimiter = '"', fieldDelimiter = ",", logging = false) {
//Split it by every character
let f=csv.split("");
//Track whether or not we're in a quote block right now
let inQuote = -1;
//Array to store all of the separated values
let vals = [[]];
//Temporary tracker for current field's string
let currentString = "";
//Track the array index for this line
let index = 0;
//Track the array index for what line we're on
let lineIndex = 0;
let lastChar = "";
//Go through every character
f.forEach((el)=>{
//If we're at a line break and we're not in a quote
if(el == "\n" && inQuote == -1) {
//Next index...
index++;
//And put the final string on the array for this line
vals[lineIndex][index] = currentString;
//Reset the string so it's squeaky clean for the next line
currentString = "";
//Take us out of a quote (shouldn't be in one anyway)
inQuote = -1;
//To the next line!!!
lineIndex++;
//Create an array at this line
vals[lineIndex]=[];
//Start at the beginning
index=0;
}
//A wild quotation mark appears! Take us out of quotes, captain. TODO add escape char support
else if(el == textDelimiter && lastChar != "\\") { console.log(lastChar); inQuote *= -1; }
//If we're not in a quote and we find a comma
else if(inQuote==-1 && el == fieldDelimiter) {
//Set the value of the current index to the string we've been working on
vals[lineIndex][index] = currentString;
//Reset our current string
currentString = "";
//Onto the next index!
index++;
}
//If it's just a plain old regular character, add it to the current string
else if(inQuote) { currentString += el; }
lastChar = el;
});
//We're at the end! Set the final string to the current string.
vals[lineIndex][index+1] = currentString;
//Say it out loud.
console.log(vals);
//Time to start working on the actual object, now that we have the array of lines. Izzy Wizzy let's get busy.
//Put together a list of headers from the first line of the above
let headers = [];
for(let v = 0; v < vals[0].length; v++) {
headers.push(vals[0][v])
}
if(logging) { console.log(headers); }
//The object our JSON data will live in
let obj = [];
//Run through the values, starting at line 1
for(let v = 1; v < vals.length; v++) {
//Shorthand the current line
let cval = vals[v];
//The object to put this line's data into
let cobj = {};
//Throw a warning out if the number of items on this line doesn't match the number of headers--the data is bad or something went wrong above.
if(cval.length != headers.length && logging) { console.warn("Number of values on line " + v + " does not match number of headers! I'll try my best!"); }
//Go through each header
for(let h = 0; h < headers.length; h++) {
//And assign the value corresponding to its position on this line
cobj[headers[h]] = cval[h];
}
//Add the current line's object to the master object array.
obj.push(cobj);
}
//Here's what we came up with.
if(logging) { console.log(obj); }
//Throw the JSON back to the people.
return JSON.stringify(obj);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment