admin管理员组

文章数量:1386798

I am getting a below structure after converting a CSV file to a JS object

"category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"

And I am trying to convert it like below

[{"category": "Test1", "name": "Name1", "includeInAuto": "true", "srNumber": 1 "testType": "type1"},
 {"category": "Test2", "name": "Name2", "includeInAuto": "true", "srNumber": 2 "testType": "type2"},
 {"category": "Test3", "name": "Name3", "includeInAuto": "true", "srNumber": 3 "testType": "type3"},
 {"category": "Test4", "name": "Name4", "includeInAuto": "true", "srNumber": 4 "testType": "type4"},
 {"category": "Test5", "name": "Name5", "includeInAuto": "true", "srNumber": 5 "testType": "type5"},
 {"category": "Test6", "name": "Name6", "includeInAuto": "true", "srNumber": 6 "testType": "type6"},
 {"category": "Test7", "name": "Name7", "includeInAuto": "true", "srNumber": 7 "testType": "type7"}]

I have tried using map like Object.entries(obj); or Object.keys(obj); or converting it an array first Array.from(obj) but not getting an expected result.

above all approaches separates each word to a single character like category to "c","a","t","e","g","o","r","y"

Can someone please help me to achieve the same?

UPDATE

if I edit the csv file in excel and then try to parse it then I get a below structure where instead of surrounding all the values with double quotes whole data is surrounded in double quotes as below

"category,name,includeInAuto,srNumber,testType 
Test1,Name1,true,1,type1 
Test2,Name2,true,2,type2
Test3,Name3,true,3,type3
Test4,Name4,true,4,type4
Test5,Name5,true,5,type5
Test6,Name6,true,6,type6
Test7,Name7,true,7,type7"

if instead of above any of the value has any special character in it lets assume if I change name7 to name,7 then FileReader return below structure

"category,name,includeInAuto,srNumber,testType 
    Test1,Name1,true,1,type1 
    Test2,Name2,true,2,type2
    Test3,Name3,true,3,type3
    Test4,Name4,true,4,type4
    Test5,Name5,true,5,type5
    Test6,Name6,true,6,type6
    Test7,\"Name,7\",true,6,type6"

in above whole csv string is in double quotes but the name name, 7 is also in double quotes with some extra slashes now instead of 4 ma separated values we have 5 ma separated values.

I am getting a below structure after converting a CSV file to a JS object

"category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"

And I am trying to convert it like below

[{"category": "Test1", "name": "Name1", "includeInAuto": "true", "srNumber": 1 "testType": "type1"},
 {"category": "Test2", "name": "Name2", "includeInAuto": "true", "srNumber": 2 "testType": "type2"},
 {"category": "Test3", "name": "Name3", "includeInAuto": "true", "srNumber": 3 "testType": "type3"},
 {"category": "Test4", "name": "Name4", "includeInAuto": "true", "srNumber": 4 "testType": "type4"},
 {"category": "Test5", "name": "Name5", "includeInAuto": "true", "srNumber": 5 "testType": "type5"},
 {"category": "Test6", "name": "Name6", "includeInAuto": "true", "srNumber": 6 "testType": "type6"},
 {"category": "Test7", "name": "Name7", "includeInAuto": "true", "srNumber": 7 "testType": "type7"}]

I have tried using map like Object.entries(obj); or Object.keys(obj); or converting it an array first Array.from(obj) but not getting an expected result.

above all approaches separates each word to a single character like category to "c","a","t","e","g","o","r","y"

Can someone please help me to achieve the same?

UPDATE

if I edit the csv file in excel and then try to parse it then I get a below structure where instead of surrounding all the values with double quotes whole data is surrounded in double quotes as below

"category,name,includeInAuto,srNumber,testType 
Test1,Name1,true,1,type1 
Test2,Name2,true,2,type2
Test3,Name3,true,3,type3
Test4,Name4,true,4,type4
Test5,Name5,true,5,type5
Test6,Name6,true,6,type6
Test7,Name7,true,7,type7"

if instead of above any of the value has any special character in it lets assume if I change name7 to name,7 then FileReader return below structure

"category,name,includeInAuto,srNumber,testType 
    Test1,Name1,true,1,type1 
    Test2,Name2,true,2,type2
    Test3,Name3,true,3,type3
    Test4,Name4,true,4,type4
    Test5,Name5,true,5,type5
    Test6,Name6,true,6,type6
    Test7,\"Name,7\",true,6,type6"

in above whole csv string is in double quotes but the name name, 7 is also in double quotes with some extra slashes now instead of 4 ma separated values we have 5 ma separated values.

Share Improve this question edited Apr 28, 2020 at 11:19 gs650x asked Apr 28, 2020 at 5:57 gs650xgs650x 4055 silver badges25 bronze badges 7
  • Thank you Teemu, yes this is a CSV, I have updated my question. – gs650x Commented Apr 28, 2020 at 6:00
  • 1 You can use this cool library csv-parse if that is okay – RaR Commented Apr 28, 2020 at 6:02
  • Thank you RaR for your response, by any chance would you please suggest a manual approach other than JS library. – gs650x Commented Apr 28, 2020 at 6:05
  • 1 Parsing CSV data is a non-trivial exercise so using an existing, well tested library would certainly be my preference over writing something bespoke. – Phil Commented Apr 28, 2020 at 6:07
  • 1 use the technique provided in this thread - stackoverflow./questions/27979002/… – Mukund Commented Apr 28, 2020 at 6:10
 |  Show 2 more ments

4 Answers 4

Reset to default 4

I would suggest using a dedicated CSV parser, like PapaParse, this is exactly what they are designed to do.

Parsing CSV data can get really tricky once you get into quoting etc.

let csv  = `category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"`;

let result = Papa.parse(csv, { header: true, dynamicTyping: true });
console.log("Result:", result);
<script src="https://cdnjs.cloudflare./ajax/libs/PapaParse/5.1.0/papaparse.min.js"></script> 

Here is my try on your SPECIFIC example WITH qoutes

const parseCsv = csv => {
  let lines = csv.split("\n");
  const header = lines.shift().split(",")
  return  lines.map(line => {
    const bits = JSON.parse("[" + line + "]")
    let obj = {};
    header.forEach((h, i) => obj[h] = bits[i]); // or use reduce here
    // optional:
    obj["includeInAuto"] = obj["includeInAuto"] === "true";
    return obj;
  });
};

const csv = `category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"`

console.log(parseCsv(csv));

Without quotes:

const parseCsv = csv => {
  let lines = csv.split(/\r?\n/);
  const header = lines.shift().split(",")
  return  lines.map(line => {
    const bits = line.split(",")
    let obj = {};
    header.forEach((h, i) => obj[h] = bits[i]); // or use reduce here
    // optional:
    obj["includeInAuto"] = obj["includeInAuto"] === "true";
    return obj;
  });
};

const csv = `category,name,includeInAuto,srNumber,testType
Test1,Name1,true,1,type1
Test2,Name2,true,1,type2
Test3,Name3,true,1,type3
Test4,Name4,true,1,type4
Test5,Name5,true,1,type5
Test6,Name6,true,1,type6
Test7,Name7,true,1,type7`


console.log(parseCsv(csv));

With escaped quotes

const parseCsv = csv => {
  let lines = csv.slice(1,csv.length-1).split(/\r?\n/);
  console.log(lines)
  const header = lines.shift().split(",")
  return  lines.map(line => {
    const bits = line.trim().split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
    let obj = {};
    header.forEach((h, i) => obj[h] = bits[i].replace(/\"/g,"")); // or use reduce here
    // optional:
    obj["includeInAuto"] = obj["includeInAuto"] === "true";
    return obj;
  });
};

const csv = `"category,name,includeInAuto,srNumber,testType 
    Test1,Name1,true,1,type1 
    Test2,Name2,true,2,type2
    Test3,Name3,true,3,type3
    Test4,Name4,true,4,type4
    Test5,Name5,true,5,type5
    Test6,Name6,true,6,type6
    Test7,\"Name,7\",true,6,type6"`


console.log(parseCsv(csv));

There are several ways to do this. Here's a snippet that uses a reducer for the csv-lines. If the csv gets more plex (e.g. nested " etc), you may want to write a parser (it's fun!) or use some external library to parse csv-files.

const csv = `category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"`.split("\n");

// get headers  
const headers = csv[0].split(",");

// helper to create a row from values 
// (using the just created headers)
const createRow = values => headers.reduce( (acc, header, i) => 
  ({...acc, [header]: values[i]}), {});

// reduce csv-lines to Array of Objects
const csv2Obj = csv
  .slice(1) // no need for headers ofcourse
  .reduce( (acc, row) => ([...acc, createRow(row.replace(/"/g, "").split(","))]), []);

console.log(csv2Obj);
.as-console-wrapper { top: 0; max-height: 100% !important; }

Here is my solution to solve this.

let csv = `category,name,includeInAuto,srNumber,testType
"Test1","Name1","true",1,"type1"
"Test2","Name2","true",1,"type2"
"Test3","Name3","true",1,"type3"
"Test4","Name4","true",1,"type4"
"Test5","Name5","true",1,"type5"
"Test6","Name6","true",1,"type6"
"Test7","Name7","true",1,"type7"`;


let data = csv.split("\n");
let title = data.shift().split(",");

let array = data.reduce((arr, row) => {
  row = row.replace(/"/g, "");
  let innerObj = row.split(",").reduce((obj, item, index) => {
    obj[title[index]] = item;
    return obj;
  }, {});
  arr.push(innerObj);
  return arr;
}, []);

console.log(array);

本文标签: javascriptHow to convert CSV to an array of JS objetcsStack Overflow