2

I am trying to convert a CSV file to a JSON nested object. I have implement the task but I have hard-coded the fields and if the CSV fields changes, I have to modify the code as well. So I am looking for a dynamic approach.

Let's say that I have already read the lines from the CSV file and I have created the following array:

    var csv = ["ChapterIndex;ArticleIndex;URL;language/chapter/en;language/title/en;language/bodyText/en;language/keywords/en;language/languageCode/en;language/chapter/es;language/title/es;language/bodyText/es;language/keywords/es;language/languageCode/es",
    "1;1;www.hotmail.com;Overview-en;Article1-en;BodyText1-en;key1,key2;en;Overview-es;Article1-es;BodyText1-es;key1,key2;es",
    "1;1;www.google.com;Overview-en;Article2-en;BodyText2-en;key1,key2;en;Overview-es;Article2-es;BodyText2-ens;key1,key2;es"]

I want to give the following format to the JSON

var obj ={
     chaterIndex:1,
     articleIndex:1,
     url:"www.test.com"
     language:[
     {  chapter:"Overvie-en",
        title:"Article1-en",
        bodyText:"bodyText-en",
        keywords:"key1,key2",
        languageCode:"en"
      },
      { chapter:"Overvie-es",
        title:"Article1-es",
        bodyText:"bodyText-es",
        keywords:"key1,key2",
        languageCode:"es"
      }]
      }

So far, I have achieved to complete half of the task but my logic is not going any further and I would like to ask for your assistance.

var csv = ["ChapterIndex;ArticleIndex;URL;language/chapter/en;language/title/en;language/bodyText/en;language/keywords/en;language/languageCode/en;language/chapter/es;language/title/es;language/bodyText/es;language/keywords/es;language/languageCode/es",
"1;1;www.hotmail.com;Overview-en;Article1-en;BodyText1-en;key1,key2;en;Overview-es;Article1-es;BodyText1-es;key1,key2;es",
"1;1;www.google.com;Overview-en;Article2-en;BodyText2-en;key1,key2;en;Overview-es;Article2-es;BodyText2-ens;key1,key2;es"]

var attrs = csv.splice(0,1);
var articles = csv
var result = csv.map(function(row) {
  var obj = {};
  var rowData = row.split(';');
  attrs[0].split(';').forEach(function(val, idx) {
      obj = constructObj(val, obj, rowData[idx]);
 });
 return obj;
})


function constructObj(str, parentObj, data) {
  if(str.split('/').length === 1) {
    parentObj[str] = data;
    return  parentObj;
  }
  var languages = [];
  var curKey = str.split('/')[0];
  if(!parentObj[curKey])
    parentObj[curKey] = {};
  parentObj[curKey] = constructObj(str.split('/').slice(1).join('/'), parentObj[curKey], data);
  return parentObj;
}

console.log(result);

7
  • 1
    Please fix the errors in your snippets first so we can run them. Commented Nov 12, 2019 at 10:36
  • Great, now what is missing? What is actually the question/problem? Commented Nov 12, 2019 at 10:42
  • The problem is that I cannot get the required format of the JSON and I do not have any idea how I can achieve it. You can see the required format if you want in the initial question.. Commented Nov 12, 2019 at 10:43
  • Do you have any influence on the csv layout? It's cumbersome to write the algorithm because the csv data is not "normalised". Commented Nov 12, 2019 at 11:17
  • I can convert the format of the CSV, it is up to me at all. What kind of format do you suggest me? Commented Nov 12, 2019 at 11:18

1 Answer 1

2

var csv = ["ChapterIndex;ArticleIndex;URL;language/chapter/en;language/title/en;language/bodyText/en;language/keywords/en;language/languageCode/en;language/chapter/es;language/title/es;language/bodyText/es;language/keywords/es;language/languageCode/es",
"1;1;www.hotmail.com;Overview-en;Article1-en;BodyText1-en;key1,key2;en;Overview-es;Article1-es;BodyText1-es;key1,key2;es",
"1;1;www.google.com;Overview-en;Article2-en;BodyText2-en;key1,key2;en;Overview-es;Article2-es;BodyText2-ens;key1,key2;es"]

function camelCase(str) { 
    return str 
        .replace(/\s(.)/g, function(a) { 
            return a.toUpperCase(); 
        }) 
        .replace(/\s/g, '') 
        .replace(/^.{0,3}/, function(b) { 
            return b.toLowerCase(); 
        }); 
} 

var attrs = csv.splice(0,1);
var articles = csv
var result = csv.map(function(row) {
  var obj = {};
  var rowData = row.split(';');
  attrs[0].split(';').forEach(function(val, idx) {
      obj = constructObj(val, obj, rowData[idx]);
 });
 return obj;
})


function constructObj(str, parentObj, data) {
  if(str.split('/').length === 1) {
    parentObj[camelCase(str)] = data;
    return  parentObj;
  }
  // language
  var curKey = str.split('/')[0]; 
  if(!parentObj[curKey]) {
    parentObj[curKey] = [];
    newLang = {} 
    newLang[str.split('/')[1]] = data;
    parentObj[curKey].push(newLang); 
  } else {
    var found = false;
    for (var i = 0; i < parentObj[curKey].length; i++) {
      if(Object.values(parentObj[curKey][i])[0] !== undefined && Object.values(parentObj[curKey][i])[0].includes(str.split('/').slice(2))) {
        parentObj[curKey][i][str.split('/')[1]] = data;
        found = true;
        break;
      }
    }
    if (!found) {
      newLang = {} 
      newLang[str.split('/')[1]] = data;
      parentObj[curKey].push(newLang);
    }
  }
  return parentObj;
}

console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.