Reputation: 65
I need to convert data from a csv file into a JavaScript object where key for each object is the id from the data. One JS object per each user.
Question: Is there a way to solve it using vanilla JS?
I need at the least a general walkthrough of what to do cause all I've been able to find is methods on how to solve this by using jQuery or JSON but for the research I am trying to understand, I can't use a specialized library, I'm only allowed to use plain VanillaJS.
Sample text data:
id first_name last_name email gender
-- ---------- --------- ----- ------
1 Gloria Mendez [email protected] Female
2 Lucy Grey [email protected] Female
3 Max Mcolom [email protected] Male
4 David Cooke [email protected] Male
5 Marwin Darge [email protected] Male
hundreds of other rows
Desired output:
{
1: {
id: 1, first_name: 'Gloria', last_name: 'Mendez', email: '[email protected]', gender: 'female'
},
2: {
id: 1, first_name: 'Lucy', last_name: 'Grey', email: '[email protected]', gender: 'female'
},
...
}
Upvotes: 1
Views: 1515
Reputation: 18281
Using vanilla JS below.
I've added comments to explain what the code is doing. It;s basically splitting the data into rows, and then cells, and doing array manipulation along the way:
let table =
`id first_name last_name email gender
-- ---------- --------- ----- ------
1 Gloria Mendez [email protected] Female
2 Lucy Grey [email protected] Female
3 Max Mcolom [email protected] Male
4 David Cooke [email protected] Male
5 Marwin Darge [email protected] Male`
// Split into rows, and then split each row into cells
let rows = table.split(/[\r\n]+/g).map(row => row.trim().split(/[\s\t]+/g));
// The first row will be the header
let header = rows[0];
// The rest is the data
let data = rows.slice(2);
// Create a function to return the desired object structure
function formatObject(headers, cells) {
return headers.reduce((result, header, idx) => {
result[header] = cells[idx];
return result;
}, {});
}
// Reduce each row into the desired format, and use the ID as a key
let result = data.reduce((res, row, idx) => {
let value = formatObject(header, row);
res[value.id] = value;
return res;
}, {});
// Log the result
console.log(result);
Upvotes: 2
Reputation: 171690
Assuming a double quoted comma separated file which is about the most common csv
format:
/* empty lines shown on purpose to approximate real file */
const csvString =
`"id","first_name","last_name","email","gender"
"1","Gloria","Mendez","[email protected]","Female"
"2","Lucy","Grey","[email protected]","Female"
"3","Max","Mcolom","[email protected]","Male"
"4","David","Cooke","[email protected]","Male"
"5","Marwin","Darge","[email protected]","Male"`;
//split string on line breaks into array of line strings
const csvLines=csvString.split('\n');
// filter empty lines out and map each line to sub array
let arr = csvLines.filter(s=>s.trim()).map(arrFromLine)
// get headings from first line
let headings = arr.shift();
// map all the other lines into objects
let res = arr.map(lineArr =>{
return lineArr.reduce((a,c, i)=>{
a[headings[i]] = c;
return a
},{})
});
// map lines to array helper function
function arrFromLine(str){
// remove quotes on each end, split at `","` to avoid any other commas in text
return str.trim().slice(1, str.length-1).split('","');
}
console.log(res)
.as-console-wrapper { max-height: 100%!important;}
Upvotes: 0
Reputation: 512
Assuming you are loading the data already, you could loop through the data and use javascripts object bracket notation to define the new properties based on the id.
If you are looking for step by step,
Create a new object, then use bracket notation to set the property of the object to the id. ex.
var obj = {};
obj[splitArray[0]] = data;
This is really rough, untested, but should get you closer to where you need to go.
Upvotes: 0
Reputation: 20808
\n
, to get rowsconst rows = csv.split('\n');
,
to get cells (if it's CSV, otherwise, \t
for TSV)const rawData = rows.map(d => d.split(',');
The first row of data is you list of keys to build objects
const headers = rawData[0]
const data = rawData.slice(2); // get rid of first 2 rows
const output = data.map(row => {
const obj = {};
headers.forEach((h, i) => obj[h] = row[i] });
return obj;
});
Of course, you need to handle all sorts of edge cases, like commas in the CSV cell, missing data etc...
I hope this gets you started.
Upvotes: 3