cdxf
cdxf

Reputation: 5648

How to join/merge json result

To reduce the payload sent to the client, my rest api only return the id of the subentities like this:

[  
   {  
      "id":369,
      "name":"Harlequin Enterprises Ltd",
      "description":"Buford Konopelski",
      "parent":{  
         "id":323
      }
   },
   {  
      "id":323,
      "name":"Heyday Books",
      "description":"Zola Rutherford",
      "parent":{  
         "id":3
      }
   },
   {  
      "id":3,
      "name":"Happy House",
      "description":"Mrs. Dwight Mohr",
      "parent":{  
         "id":null
      }
   }
]

Are there any libraries help me join/merge all the enities into this:

[  
   {  
      "id":369,
      "name":"Harlequin Enterprises Ltd",
      "description":"Buford Konopelski",
      "parent":{  
         "id":323,
         "name":"Heyday Books",
         "description":"Zola Rutherford",
         "parent":{  
            "id":3,
            "name":"Happy House",
            "description":"Mrs. Dwight Mohr",
            "parent":{  
               "id":null
            }
         }
      }
   },
   {  
      "id":323,
      "name":"Heyday Books",
      "description":"Zola Rutherford",
      "parent":{  
         "id":3,
         "name":"Happy House",
         "description":"Mrs. Dwight Mohr",
         "parent":{  
            "id":null
         }
      }
   },
   {  
      "id":3,
      "name":"Happy House",
      "description":"Mrs. Dwight Mohr",
      "parent":{  
         "id":null
      }
   }
]

// Here is a simplified solution inspired from IVO GELOV solution:

var mapID = inputJSON.map((item) => item.id);
// attach parents to childreen
var normalized = inputJSON.map((item) =>
{
    var parentIndex = mapID.indexOf(item.parent.id);
    item.parent = inputJSON[parentIndex];
    return item;
});
console.log(JSON.stringify(normalized))

Upvotes: 0

Views: 60

Answers (4)

Vignesh Raja
Vignesh Raja

Reputation: 8761

You can use Array.forEach to iterate and Array.reduce to construct every object based on parent key.

var arr = [  
   {  
      "id":369,
      "name":"Harlequin Enterprises Ltd",
      "description":"Buford Konopelski",
      "parent":{  
         "id":323
      }
   },
   {  
      "id":323,
      "name":"Heyday Books",
      "description":"Zola Rutherford",
      "parent":{  
         "id":3
      }
   },
   {  
      "id":3,
      "name":"Happy House",
      "description":"Mrs. Dwight Mohr",
      "parent":{  
         "id":null
      }
   }
];

arr.forEach(obj => {
    obj = arr.reduce(acc => {
        var parent=acc.parent;
        while(parent.parent) parent=parent.parent;
        if(parent.id)
        {
            Object.assign(parent, arr.find(function(o){return o.id==parent.id}));
        }
        return acc;
    })
});

console.log(arr)

Upvotes: 0

Syed Ayesha Bebe
Syed Ayesha Bebe

Reputation: 1448

You can handle this using for loop

var final_Array = [];
var data = [  
   {  
      "id":369,
      "name":"Harlequin Enterprises Ltd",
      "description":"Buford Konopelski",
      "parent":{  
         "id":323
      }
   },
   {  
      "id":323,
      "name":"Heyday Books",
      "description":"Zola Rutherford",
      "parent":{  
         "id":3
      }
   },
   {  
      "id":3,
      "name":"Happy House",
      "description":"Mrs. Dwight Mohr",
      "parent":{  
         "id":null
      }
   }
]

for(var i=0;i<data.length;i++){
    var f = 0;
    for(var j=0;j<data.length;j++){
        if(data[i].parent.id==data[j].id){
            var r = {
                 "id":data[i].id,
                 "name":data[i].name,
                 "description":data[i].description,
                 "parent":data[j]
            }
            final_Array.push(r);
        }
        else if(data[i].parent.id==null){
            f++;        
        }
    }
    if(j==f){
            var r = {
                 "id":data[i].id,
                 "name":data[i].name,
                 "description":data[i].description,
                 "parent":data[i].parent
            }
            final_Array.push(r);
    }
}
if(i==data.length){
    console.log(final_Array);
}

Hope this helps

Upvotes: 0

Edwin
Edwin

Reputation: 2278

You can do this recursivley, but you will have to mind the performance (or not).

var arr = [{
    "id": 369,
    "name": "Harlequin Enterprises Ltd",
    "description": "Buford Konopelski",
    "parent": {
      "id": 323
    }
  },
  {
    "id": 323,
    "name": "Heyday Books",
    "description": "Zola Rutherford",
    "parent": {
      "id": 3
    }
  },
  {
    "id": 3,
    "name": "Happy House",
    "description": "Mrs. Dwight Mohr",
    "parent": {
      "id": null
    }
  }
];

function findId(a, id) {
  var elem = null;
  a.forEach((element) => {
    if (element.id === id) {
      elem = JSON.parse(JSON.stringify(element));
      if (null !== element.parent.id) {
        var parentElem = findId(a, element.parent.id);
        elem.parent = JSON.parse(JSON.stringify(parentElem));
      }
    }
  });
  return elem;
}
var newArr = [];
arr.forEach((element) => {
  var elem = findId(arr, element.id);
  newArr.push(elem);
});

console.log(newArr);

Upvotes: 0

IVO GELOV
IVO GELOV

Reputation: 14269

You have to use a map

var inputJSON, mapID = {};

// create the map - allowing to get an item by ID
inputJSON.forEach((item) =>
{
  mapID[item.id] = item;
});

// attach parents to childreen
inputJSON.forEach((item) =>
{
  if(item.parent && item.parent.id && mapID[item.parent.id]) 
  {
    item.parent = mapID[item.parent.id]
  }
});

Upvotes: 1

Related Questions