HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Converts the JSON object to another structure of JSON

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
theconvertsanotherstructurejsonobject

Problem

I want a JSON object of the following structure to plot a chart

chartGroup = [{name: 'AB', to: 254, from: 247},
              {name: 'CD', to: 208, from: 211},
              {name: 'AC', to: 46, from: 41},
              {name: 'AD', to: 10, from: 38},
              {name: 'BC', to: 56, from: 55},
              {name: 'BD', to: 44, from: 45}
             ];


from the below JSON object which I get from Database

data = [{from: "B", to: "D", count: 44},
        {from: "D", to: "B", count: 45},
        {from: "A", to: "B", count: 254},
        {from: "C", to: "D", count: 208},
        {from: "B", to: "A", count: 247},
        {from: "C", to: "A", count: 41},
        {from: "A", to: "D", count: 10},
        {from: "A", to: "C", count: 46},
        {from: "D", to: "C", count: 211},
        {from: "D", to: "A", count: 38},
        {from: "C", to: "B", count: 55},
        {from: "B", to: "C", count: 56}];


To create chartGroup from data, I'm using the below code :

```
var chartPoints = {};
data.forEach(function(s) {
if((s.from == "A" && s.to == "B") || (s.from == "B" && s.to == "A")) {
if(s.to == "B"){
chartPoints["to"] = s.count;
}else{
chartPoints["from"] = s.count;
}
chartPoints["name"] = "AB";

}
});
chartGroup.push(chartPoints);

var chartPoints = {};
data.forEach(function(s) {
if((s.from == "C" && s.to == "D") || (s.from == "D" && s.to == "C")) {
if(s.to == "D"){
chartPoints["to"] = s.count;
}else{
chartPoints["from"] = s.count;
}
chartPoints["name"] = "CD";
}
});
chartGroup.push(chartPoints);

var chartPoints = {};
data.forEach(function(s) {
if((s.from == "A" && s.to == "C") || (s.from == "C" && s.to == "A")) {
if(s.to == "C") {
chartPoints["to"] = s.

Solution

Your code had a lot of loops so I tried to squish it into one reducer for you. I think this will work;

var output = data.reduce(function (out, d) {
   var edges = [d.from, d.to].sort();
   var key = edges.join("");
   var obj = out.find(function (o) { return o.name === key; });
   if (!obj) {
     obj = {
       name: key,
       from: 0,
       to: 0
     };
     out.push(obj);
   }
   obj.to += edges[0] === d.from ? d.count : 0;
   obj.from += edges[1] === d.from ? d.count : 0;

   return out;
 }, []);

console.log(output);


Output:

[
  {
    "name": "BD",
    "from": 45,
    "to": 44
  },
  {
    "name": "AB",
    "from": 247,
    "to": 254
  },
  {
    "name": "CD",
    "from": 211,
    "to": 208
  },
  {
    "name": "AC",
    "from": 41,
    "to": 46
  },
  {
    "name": "AD",
    "from": 38,
    "to": 10
  },
  {
    "name": "BC",
    "from": 55,
    "to": 56
  }
]


Here's an example on JsBin

Reducers are super powerful when you need to convert an array into a different array or value.

In this case I'm iterating over the data array, and creating the key (AB) by sorting the from and to values.

Then I check the output to see if we've already used that key, if so we append to that existing object, if not then we create it.

Code Snippets

var output = data.reduce(function (out, d) {
   var edges = [d.from, d.to].sort();
   var key = edges.join("<->");
   var obj = out.find(function (o) { return o.name === key; });
   if (!obj) {
     obj = {
       name: key,
       from: 0,
       to: 0
     };
     out.push(obj);
   }
   obj.to += edges[0] === d.from ? d.count : 0;
   obj.from += edges[1] === d.from ? d.count : 0;

   return out;
 }, []);

console.log(output);
[
  {
    "name": "B<->D",
    "from": 45,
    "to": 44
  },
  {
    "name": "A<->B",
    "from": 247,
    "to": 254
  },
  {
    "name": "C<->D",
    "from": 211,
    "to": 208
  },
  {
    "name": "A<->C",
    "from": 41,
    "to": 46
  },
  {
    "name": "A<->D",
    "from": 38,
    "to": 10
  },
  {
    "name": "B<->C",
    "from": 55,
    "to": 56
  }
]

Context

StackExchange Code Review Q#120242, answer score: 2

Revisions (0)

No revisions yet.