1

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?

Dvd
  • 117
  • 3
  • 7
  • 1
    Does this answer your question? [Convert CSV data into JSON format using Javascript](https://stackoverflow.com/questions/27979002/convert-csv-data-into-json-format-using-javascript) – Alberto Anderick Jr May 01 '21 at 17:04

1 Answers1

4

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)
Richard Zhan
  • 460
  • 3
  • 10
  • 1
    Hi Richard, i'm newbie in Javascript and I have the same kind of problem of this question, i was wondering, for example, if I wanted to convert the Coordinates column in a integer, what can I do? – Dario_Della May 11 '21 at 09:57