1

I'm trying to convert a data from csv to json, but I wanted the data to follow some hierarchy.

This is my CSV

link,model,role,access
link1,model1,role1,true
link1,model1,role2,true
link1,model1,role3,true
link1,model1,role4,true
link1,model2,role1,false
link1,model2,role2,false
link1,model2,role3,false
link1,model2,role4,false
link2,model1,role1,false
link2,model1,role2,true
link2,model1,role3,false
link2,model1,role4,true
link2,model2,role1,false
link2,model2,role2,true
link2,model2,role3,false
link2,model2,role4,true

Expected result

"link1": {
    "model1": {
        "role1": true,
        "role2": true,
        "role3": true,
        "role4": true,
    },
    "model2": {
        "role1": false,
        "role2": false,
        "role3": false,
        "role4": false,
    }
},
"link2": {
    "model1": {
        "role1": false,
        "role2": true,
        "role3": false,
        "role4": true,
    },
    "model2": {
        "role1": false,
        "role2": true,
        "role3": false,
        "role4": true,
    }
}

I tried to do it from this jquery - creating nested json from flat json, but the thing is it has only 1 level, but in my case it's two levels.

I thought of doing it something like this,

data.forEach(function(val) {
        newData[val.link] = {val.model :  {val.role: val.access}};
    });

But couldn't really get it to work. I'm pretty new to the data part, any help or suggestion will be much appreciated.

Thanks in advance

2 Answers 2

2

It is actually simple enough to parse the CSV format in this particular case. See the snippet below.

I have split the main CSV string by \n to get the lines. Now skipping the first line (which is the header), you just need to get value of every column and push it into the result obj.

var str = `link,model,role,access
link1,model1,role1,true
link1,model1,role2,true
link1,model1,role3,true
link1,model1,role4,true
link1,model2,role1,false
link1,model2,role2,false
link1,model2,role3,false
link1,model2,role4,false
link2,model1,role1,false
link2,model1,role2,true
link2,model1,role3,false
link2,model1,role4,true
link2,model2,role1,false
link2,model2,role2,true
link2,model2,role3,false
link2,model2,role4,true`;

var lines = str.split('\n');
var obj = {};
// Ignore the first line as it contains only the header info.
for(var i = 1; i < lines.length; i++) {
  var lineItems = lines[i].split(',');
  var link = lineItems[0];
  var model = lineItems[1];
  var role = lineItems[2];
  var roleValue = lineItems[3];
  
  if(obj[link] == undefined) {
    obj[link] = {};
  }
   
  if(obj[link][model] == undefined) {
    obj[link][model] = {};
  }
  
  obj[link][model][role] = roleValue;
}

console.log(obj);

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

7 Comments

Wow man!!! This is so cool. Thanks a lot, I have another doubt, can you pls help me out?
Yeah, sure. Anything related to this question?
Yes it is related to this question, I just put a same CSV over there. But I have a lot of lines, I found a way to convert them to JSON using d3.js. With the converted JSON will this code work?
Which question? I don't see any links in your code!
The same question for which you've already answered me. After I convert the CSV to JSON using d3.js, I have a JSON output stored in a variable. Will I be able to pass the JSON to your code which you answered me now?
|
0

Since its tagged in d3, a d3 way would be something like this:

  • Using d3.CSV
  • Then rolling up values using d3.nest

    d3.csv("https://gist.githubusercontent.com/cyrilcherian/649d692647ddc70afda93be607427221/raw/bbb95b10d1aca62b17f75534039fb7e8a7c911ba/some.csv", function(data) {;
      var nested_data = d3.nest()
        .key(function(d) {
          return d.link;
        })
        .key(function(d) {
          return d.model;
        })
        .rollup(function(leaves) {
          return {
            role1: leaves.find(d => d.role == "role1").access,
            role2: leaves.find(d => d.role == "role2").access,
            role3: leaves.find(d => d.role == "role3").access,
            role4: leaves.find(d => d.role == "role4").access
          };
        })
        .entries(data);
      console.log(nested_data)
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.js"></script>

It returns data in a key/values fashion which need to be mapped as per your JSON format.

Not complete but I thought of sharing.

3 Comments

Here is a plunk i was playing around in case you need it plnkr.co/edit/jemffA2RHPFjJdSHjz3g?p=preview
Hey, thank you for your response. But the nested_data isn't the format what I'm looking for. I don't want the "key" or "values" to be present there instead I only want the name of it. Only "models" and "link".
yep exactly, the one you accepted as answer is a better way out. using d3.nesting i cant make it as per the structure you expecting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.