Nihar
Nihar

Reputation: 373

Modify Json data to create new object by JavaScript

I have a json data as following

{
  "file1": {
    "function1": {
      "calls": {
        "439:0": [
          "441:24"
        ],
        "441:24": [
          "443:4"
        ],
        "443:4": [
          "447:7",
          "445:10"
        ],
        "445:10": [
          "449:4"
        ],
        "447:7": [
          "449:4"
        ]
      }
    },
    "function2": {
      "calls": {
        "391:0": [
          "393:8"
        ],
        "393:8": [
          "397:7"
        ],
        "397:7": [
          "395:27"
        ]
      }
    },
    "function3": {
      "calls": null
    },
    "function4": {
      "calls": null
    }
  },
  "file2": {
    "function5": {
      "calls": null
    },
    "function6": {
      "calls": {
        "391:0": [
          "393:8"
        ],
        "393:8": [
          "397:7"
        ],
        "397:7": [
          "395:27"
        ]
      }
    }
  }
}

I need to convert it following format for "function1"

    {
  "nodes": [
    {
      "id": "439:0",
      "line": "439:0"
    },
    {
      "id": "441:24",
      "line": "441:24"
    },
    {
      "id": "443:4",
      "line": "443:4"
    },
    {
      "id": "447:7",
      "line": "447:7"
    },
    {
      "id": "445:10",
      "line": "445:10"
    },
    {
      "id": "449:4",
      "line": "449:4"
    }
  ],
  "links": [
    {
      "source": "439:0",
      "target": "441:24"
    },
    {
      "source": "441:24",
      "target": "443:4"
    },
    {
      "source": "443:4",
      "target": "447:7"
    },
    {
      "source": "443:4",
      "target": "445:10"
    },
    {
      "source": "445:10",
      "target": "449:4"
    },
    {
      "source": "447:7",
      "target": "449:4"
    }
  ]
}

Where the "call" keys are line and id in "nodes" and source in "links". Targets are the values inside calls. If any key has multiple values than for each value it will create a source-target pair.

This will be used later as data.nodes.map(function(d){return d.line})

I have tried the following code but its not working properly. Its giving an array with correct information but the way i need to use it in further steps, its not working there. Its giving errors like Property 'nodes' does not exist on type 'any[]'.

let res = {}
let nodes = []
let links = []
Object.entries(input0).map(([fileName, fileObject]) => {
  Object.entries(fileObject).map(([functionName, functionObject]) => {
    if(functionName=="function1"){
      Object.entries(functionObject).map(([functionKey, functionValue]) => { 
        if(functionKey === "calls") {
          if(functionValue != null){
            Object.entries(functionValue).map(([callKey, callObject]) => {     
              nodes = [...nodes,{"id": callKey, "line": callKey}] 
              callObject.forEach(x => {
                links = [...links,{"source": callKey, "target": x}] 
              });
              res = {"nodes": nodes, "links": links} //nodes.concat(links)
            })                     
          }
        }
      })
    }
  })
})
console.log(res)

Someone please help. Thank you for your time.

Upvotes: 0

Views: 120

Answers (2)

kalai
kalai

Reputation: 186

you can try this ,this should be working fine.

           var res = {};
            var nodes = [];
            var Links = [];
            var json = '{"file1":{"function1":{"calls":{"439:0":["441:24"],"441:24":["443:4"],"443:4":["447:7","445:10"],"445:10":["449:4"],"447:7":["449:4"]}},"function2":{"calls":{"391:0":["393:8"],"393:8":["397:7"],"397:7":["395:27"]}},"function3":{"calls":null},"function4":{"calls":null}},"file2":{"function5":{"calls":null},"function6":{"calls":{"391:0":["393:8"],"393:8":["397:7"],"397:7":["395:27"]}}}}';
            var jsonObj = JSON.parse(json);
            if ("function1" in jsonObj.file1) {
                if ('calls' in jsonObj.file1.function1) {
                    for (var i = 0; Object.keys(jsonObj.file1.function1.calls).length > i; i++) {
                        nodes.push({ "id": Object.keys(jsonObj.file1.function1.calls)[i], "line": Object.keys(jsonObj.file1.function1.calls)[i] });
                            for (var j = 0; Object.values(jsonObj.file1.function1.calls)[i].length > j; j++) {
                                Links.push({ "source": Object.keys(jsonObj.file1.function1.calls)[i], "target": Object.values(jsonObj.file1.function1.calls)[i][j] });
                        }
                    }
                    res = { "nodes": nodes, "links": Links }
                    console.log(res);
                }
            }

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386776

You could omit unwanted properies and head for nested once and build a new set of nodes by checking existent nodes and assign all links without further checking.

function getNodesLinks(object, result = { nodes: [], links: [] }) {
    if (object.calls === null) return result;
    if (!object.calls) {
        Object.values(object).forEach(v => getNodesLinks(v, result));
        return result;
    }
    Object.entries(object.calls).forEach(([source, targets]) => {
        if (!result.nodes.some(({ id }) => id === source)) {
            result.nodes.push({ id: source, line: source });
        }
        targets.forEach(target => {
            if (!result.nodes.some(({ id }) => id === target)) {
                result.nodes.push({ id: target, line: target });
            }
            result.links.push({ source, target });
        });
    });
    return result;
}

var data = { file1: { function1: { calls: { "439:0": ["441:24"], "441:24": ["443:4"], "443:4": ["447:7", "445:10"], "445:10": ["449:4"], "447:7": ["449:4"] } }, function2: { calls: { "391:0": ["393:8"], "393:8": ["397:7"], "397:7": ["395:27"] } }, function3: { calls: null }, function4: { calls: null } }, file2: { function5: { calls: null }, function6: { calls: { "391:0": ["393:8"], "393:8": ["397:7"], "397:7": ["395:27"] } } } },
    result = getNodesLinks(data);

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

Upvotes: 1

Related Questions