Skip to content
Advertisement

Converting CSV to JSON using JavaScript

I’m learning JavaScript and i’m trying to convert a CSV file to a JSON.

The structure of my csv is :

Name Class region_count Coordinates
foto_4.jpeg soccer 1 “all_points_x”:[90,80,77,74,82,89,113,142,146,153,162,174,184,199,220,235,261,280,289,298,298,287,279,276,271,268,265,266,270,270,262,249,236,222,213,188,170,151,114,92],”all_points_y”:[145,171,192,211,241,263,291,308,310,301,288,275,265,257,246,244,241,238,241,243,235,223,208,196,176,165,148,134,119,114,109,99,96,93,90,89,89,94,116,146]
foto_4.jpeg tennis 2 “all_points_x”:[394,418,445,456,467,472,469,461,448,436,425,412,402,394,384,383,392],”all_points_y”:[276,259,260,266,279,296,313,327,335,341,342,338,334,326,313,294,279]
foto_5.jpeg basket 1 “all_points_x”:[345,373,427,479,509,540,553,549,541,526,490,467,455,447,430,421,411,406,400,394,391,381,368,349,337,327,320,308,301],”all_points_y”:[23,11,7,22,44,89,140,182,207,230,261,274,263,260,255,255,255,261,268,273,278,286,279,273,268,258,250,242,237]

the desired json structure is:

{"foto_1jpg.jpg121349":{"filename":"foto_1jpg.jpg","regions":[{"shape_attributes":{"all_points_x":[154,157,230,275,278,218,160,112,113,154],"all_points_y":[461,461,455,495,576,625,625,563,505,463]},"region_attributes":{"name":"tennis"}},{"shape_attributes":{"all_points_x":[446,557,685,795,826,815,738,628,505,422,346,331,354,443],"all_points_y":[230,186,212,321,411,538,641,687,684,632,525,426,331,224]},"region_attributes":{"name":"soccer"}}],"file_attributes":{}},"foto_2.jpg325912":{"filename":"foto_2.jpg","regions":[{"shape_attributes":{"all_points_x":[331,403,518,626,688,734,758,681,594,484,369,314,282,274,329],"all_points_y":[399,340,316,342,380,463,607,736,787,796,745,683,592,503,405]},"region_attributes":{"name":"soccer"}},{"shape_attributes":{"name":"polygon","all_points_x":[972,887,830,802,789,804,857,963,1050,1135,1220,1284,1314,1307,1263,1178,1116,1057,955],"all_points_y":[144,195,261,327,397,484,579,639,660,647,603,524,424,335,238,174,146,140,157]}],"file_attributes":{}},"foto_3.jpg196633":{"filename":"foto_3.jpg","regions":[{"shape_attributes":{"name":"polygon","all_points_x":[65,43,49,107,160,215,290,351,406,431,409,373,334,274,203,150,107,70],"all_points_y":[349,421,503,586,622,630,629,593,537,465,356,313,283,264,256,278,303,346]},"region_attributes":{"name":"soccer"}}],"file_attributes":{}}}


I tried to convert this CSV to JSON with this code

var csv = `,Name,Class,Region_count,Coordinates
0,foto_1jpg.jpg,tennis,1,"""all_points_x"":[154,157,230,275,278,218,160,112,113,154],""all_points_y"":[461,461,455,495,576,625,625,563,505,463]"
1,foto_1jpg.jpg,soccer,2,"""all_points_x"":[446,557,685,795,826,815,738,628,505,422,346,331,354,443],""all_points_y"":[230,186,212,321,411,538,641,687,684,632,525,426,331,224]"
2,foto_1jpg.jpg,basket,3,"""all_points_x"":[941,1065,1161,1310,1438,1497,1509,1471,1382,1279,1124,998,916,874,847,874,938],""all_points_y"":[132,44,26,48,144,266,396,514,628,673,687,631,560,479,328,233,135]"
3,foto_2jpg.jpg,soccer,1,"all_points_x:[331,403,518,626,688,734,758,681,594,484,369,314,282,274,329],""all_points_y"":[399,340,316,342,380,463,607,736,787,796,745,683,592,503,405]"
4,foto_2jpg.jpg,basket,2,"""all_points_x"":[972,887,830,802,789,804,857,963,1050,1135,1220,1284,1314,1307,1263,1178,1116,1057,955],""all_points_y"":[144,195,261,327,397,484,579,639,660,647,603,524,424,335,238,174,146,140,157]"
5,foto_2jpg.jpg,tennis,3,"all_points_x:[1186,1233,1273,1282,1267,1231,1178,1154,1135,1131,1142,1182],""all_points_y"":[921,921,891,845,806,777,775,789,819,859,895,919]"
6,foto_3jpg.jpg,soccer,1,"""all_points_x"":[65,43,49,107,160,215,290,351,406,431,409,373,334,274,203,150,107,70],""all_points_y"":[349,421,503,586,622,630,629,593,537,465,356,313,283,264,256,278,303,346]"
7,foto_3jpg.jpg,basket,2,"""all_points_x"":[523,588,647,739,809,854,871,877,860,845,830,823,816,811,804,802,796,774,765,753,726,712,699,685,682,671,670,666,664,632,601,583,549,515,496,469,446,448,467,518],""all_points_y"":[242,203,196,206,247,307,361,436,491,509,515,521,530,537,549,561,572,583,583,562,550,547,554,557,571,578,591,601,620,615,612,608,588,552,532,496,428,370,319,244]"
8,foto_3jpg.jpg,tennis,3,"all_points_x:[838,881,901,917,912,888,869,845,821,804,792,791,813],""all_points_y"":[544,544,569,600,627,646,654,654,651,634,601,578,552]"`;


var map = {};


var rows = csv.split(/n/g);

var keys = rows.shift().split(",");

rows.forEach(raw_row=>{
  
  var row = {};
  var row_key;
  
  var columns = raw_row.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
  
  columns.forEach((column, index)=>{
    
    var key = keys[index];
    
    if(!key) return;
    
    if(key === 'Name'){
      row_key = column;
      return;
    }
        
   
    if(key === "Coordinates"){
      
      
      column = column.replace(/""/g, '"');
      
     
      column = column.substring(1, column.length-1);
      
      
      column = column.replace(/([a-zA-Z_]+):/g, `"$1":`);
      
      
      try{ column = JSON.parse(`{${column}}`); }catch(e){}
    }
    
    
    row[key] = column;
    
  });
  

  map[row_key] = row;
});

console.log(map);

the JSON create is this:

{"foto_1jpg.jpg":{"Class":"basket","region_count":"3","Coordinates":{"all_points_x":[941,1065,1161,1310,1438,1497,1509,1471,1382,1279,1124,998,916,874,847,874,938],"all_points_y":[132,44,26,48,144,266,396,514,628,673,687,631,560,479,328,233,135]}},"foto_2jpg.jpg":{"Class":"tennis","region_count":"3","Coordinates":{"all_points_x":[1186,1233,1273,1282,1267,1231,1178,1154,1135,1131,1142,1182],"all_points_y":[921,921,891,845,806,777,775,789,819,859,895,919]}},"foto_3jpg.jpg":{"Class":"tennis","region_count":"3","Coordinates":{"all_points_x":[838,881,901,917,912,888,869,845,821,804,792,791,813],"all_points_y":[544,544,569,600,627,646,654,654,651,634,601,578,552]}}}


With my code I can’t iterate for all the polygons contained in one picture and I can’t add region key (example region) that contains other keys

How can I reach my desired output?

Advertisement

Answer

Your initial approach looks pretty good. We just need some more modifications to the data you generated. Instead of directly mapping each row to JSON, first keep data in the array as a line item, and then build the JSON data as follows.

var csv = `,Name,Class,Region_count,Coordinates
0,foto_1jpg.jpg,tennis,1,"""all_points_x"":[154,157,230,275,278,218,160,112,113,154],""all_points_y"":[461,461,455,495,576,625,625,563,505,463]"
1,foto_1jpg.jpg,soccer,2,"""all_points_x"":[446,557,685,795,826,815,738,628,505,422,346,331,354,443],""all_points_y"":[230,186,212,321,411,538,641,687,684,632,525,426,331,224]"
2,foto_1jpg.jpg,basket,3,"""all_points_x"":[941,1065,1161,1310,1438,1497,1509,1471,1382,1279,1124,998,916,874,847,874,938],""all_points_y"":[132,44,26,48,144,266,396,514,628,673,687,631,560,479,328,233,135]"
3,foto_2jpg.jpg,soccer,1,"all_points_x:[331,403,518,626,688,734,758,681,594,484,369,314,282,274,329],""all_points_y"":[399,340,316,342,380,463,607,736,787,796,745,683,592,503,405]"
4,foto_2jpg.jpg,basket,2,"""all_points_x"":[972,887,830,802,789,804,857,963,1050,1135,1220,1284,1314,1307,1263,1178,1116,1057,955],""all_points_y"":[144,195,261,327,397,484,579,639,660,647,603,524,424,335,238,174,146,140,157]"
5,foto_2jpg.jpg,tennis,3,"all_points_x:[1186,1233,1273,1282,1267,1231,1178,1154,1135,1131,1142,1182],""all_points_y"":[921,921,891,845,806,777,775,789,819,859,895,919]"
6,foto_3jpg.jpg,soccer,1,"""all_points_x"":[65,43,49,107,160,215,290,351,406,431,409,373,334,274,203,150,107,70],""all_points_y"":[349,421,503,586,622,630,629,593,537,465,356,313,283,264,256,278,303,346]"
7,foto_3jpg.jpg,basket,2,"""all_points_x"":[523,588,647,739,809,854,871,877,860,845,830,823,816,811,804,802,796,774,765,753,726,712,699,685,682,671,670,666,664,632,601,583,549,515,496,469,446,448,467,518],""all_points_y"":[242,203,196,206,247,307,361,436,491,509,515,521,530,537,549,561,572,583,583,562,550,547,554,557,571,578,591,601,620,615,612,608,588,552,532,496,428,370,319,244]"
8,foto_3jpg.jpg,tennis,3,"all_points_x:[838,881,901,917,912,888,869,845,821,804,792,791,813],""all_points_y"":[544,544,569,600,627,646,654,654,651,634,601,578,552]"`;

var items = []

var rows = csv.split(/n/g);
var keys = rows.shift().split(",");

rows.forEach(raw_row => {  
  var row = {};
  var columns = raw_row.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
  
  columns.forEach((column, index)=>{
    var key = keys[index];
    if(!key) return;       
    if(key === "Coordinates"){
      column = column.replace(/""/g, '"');
      column = column.substring(1, column.length-1);
      column = column.replace(/([a-zA-Z_]+):/g, `"$1":`);
      try{ column = JSON.parse(`{${column}}`); }catch(e){}
    }
    row[key] = column;
    
  });
  items.push(row);
});

const map = {}
for (const item of items) {
  if (!map[item['Name']]) {
    map[item['Name']] = {
      'filename': item['Name'],
      'regions': [],
      'file_attributes': {}
    }
  }
  map[item['Name']].regions.push(
    {
      "shape_attributes": item['Coordinates'],
      "region_attributes": { "name": item['Class'] }
    }
  )
}

console.log(map)
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement