1

I am working with javascript and I would like to join two JSON file into a single JSON object that contains all the attributes. Right now the two JSON file have separate information but I need to combine them.

Station Information JSON - Example Below:

{  
   "last_updated":1493307962,
   "ttl":10,
   "data":{  
      "stations":[  
         {  
            "station_id":"219",
            "name":"Central Square - East Boston",
            "short_name":"A32036",
            "lat":42.37454454514976,
            "lon":-71.03837549686432,
            "region_id":10,
            "rental_methods":[  
               "KEY",
               "CREDITCARD"
            ],
            "capacity":19,
            "eightd_has_key_dispenser":false
         },
         {  
            "station_id":"220",
            "name":"Test 1",
            "short_name":"Test 1",
            "lat":0,
            "lon":0,
            "rental_methods":[  
               "KEY",
               "CREDITCARD"
            ],
            "capacity":0,
            "eightd_has_key_dispenser":false
         }
      ]
   }
} 

Station Status JSON - Example Below:

{  
   "last_updated":1493308075,
   "ttl":10,
   "data":{  
      "stations":[
         {  
            "station_id":"219",
            "num_bikes_available":7,
            "num_bikes_disabled":1,
            "num_docks_available":11,
            "num_docks_disabled":0,
            "is_installed":1,
            "is_renting":1,
            "is_returning":1,
            "last_reported":1493283725,
            "eightd_has_available_keys":false
         },
         {  
            "station_id":"220",
            "num_bikes_available":0,
            "num_bikes_disabled":0,
            "num_docks_available":0,
            "num_docks_disabled":0,
            "is_installed":0,
            "is_renting":0,
            "is_returning":0,
            "last_reported":0,
            "eightd_has_available_keys":false
         }
      ]
   }
}

Specifically, I looked at this post (How to join two json object in javascript, without using JQUERY) but the two JSON files have more complex structure, so I could not make it work.

Any suggestion will be really appreciated.

Community
  • 1
  • 1
  • 5
    As it stands currently, your question is entirely reliant on external resources. To make your question complete, consider supplementing each JSON link with a small snippet/example of its contents. **EDIT:** I've decided to edit your question myself - I hope you don't mind. – Tyler Roper Apr 27 '17 at 15:44
  • 1
    Note that you might get more hits on your research if you leave out the "JSON". Your files are in JSON format, but once they're included/parsed, they are just JavaScript objects. So maybe search for "How to join two objects in JavaScript". This technique is also called "merging" so that might help as well. – Heretic Monkey Apr 27 '17 at 15:51
  • What is expected result? – guest271314 Apr 27 '17 at 15:52
  • Have you tried the solutions in that post? Could you provide what you tried and how the results differed from what you want? – Heretic Monkey Apr 27 '17 at 15:57
  • We need to know logic behind data before suggesting you how to combine them. – Sergey Orlov Apr 27 '17 at 16:02
  • These are not JSON files--they are JavaScript objects--and JavaScript objects do not have "attributes". –  Apr 27 '17 at 16:48

3 Answers3

0

I assume you're not interested in the parameters surrounding the stations. You could use this code to get an array of stations with all the information based on station_id

obj1.data.stations.map(el1 => Object.assign({},el1,obj2.data.stations.filter(el2 => el2.station_id === el1.station_id)));

Where obj1 and obj2 are your JSONs.

"[
  {
    "0": {
      "station_id": "219",
      "num_bikes_available": 7,
      "num_bikes_disabled": 1,
      "num_docks_available": 11,
      "num_docks_disabled": 0,
      "is_installed": 1,
      "is_renting": 1,
      "is_returning": 1,
      "last_reported": 1493283725,
      "eightd_has_available_keys": false
    },
    "station_id": "219",
    "name": "Central Square - East Boston",
    "short_name": "A32036",
    "lat": 42.37454454514976,
    "lon": -71.03837549686432,
    "region_id": 10,
    "rental_methods": [
      "KEY",
      "CREDITCARD"
    ],
    "capacity": 19,
    "eightd_has_key_dispenser": false
  },
  {
    "0": {
      "station_id": "220",
      "num_bikes_available": 0,
      "num_bikes_disabled": 0,
      "num_docks_available": 0,
      "num_docks_disabled": 0,
      "is_installed": 0,
      "is_renting": 0,
      "is_returning": 0,
      "last_reported": 0,
      "eightd_has_available_keys": false
    },
    "station_id": "220",
    "name": "Test 1",
    "short_name": "Test 1",
    "lat": 0,
    "lon": 0,
    "rental_methods": [
      "KEY",
      "CREDITCARD"
    ],
    "capacity": 0,
    "eightd_has_key_dispenser": false
  }
]"
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
dinigo
  • 6,872
  • 4
  • 37
  • 48
  • I feel like this is a little weak to be an answer. Not only does it include node syntax (which OP didn't mention or tag), it's also the same as the accepted answer to the question that OP already said didn't achieve his desired result. – Tyler Roper Apr 27 '17 at 15:55
  • that's true @Santi. How about now? – dinigo Apr 27 '17 at 16:10
0

I guess you want to merge stations. If both stations arrays are in the same order (as your example shows) you can do it easily this way:

First parse both JSON using JSON.parse and then merge each station object using Object.assign

var obj1 = JSON.parse('your-first-json');
var obj2 = JSON.parse('your-second-json');

obj1.data.stations.forEach(function(item, i) {
    Object.assign(item, obj2.data.stations[i])
});
//obj1 will have the obj2 sation data.

If the arrays are not in the same order (same index - same ID) you'll have to perform a lookup by ID before performing the merge.

You could use Array.find for that:

obj1.data.stations.forEach(function(station, i){

    var station2 = obj2.data.stations.find(function(item) {
        return item.station_id === station.station_id;
    });

    Object.assign(station, station2);
});

I don't know where you're running this, if in node or in the browser, but there are polyfills for both Object.assign & Array.find in the links I've provided. Also there are many similar functions using jQuery or other similar libraries.

var obj1 = {
   "last_updated":1493307962,
   "ttl":10,
   "data":{
      "stations":[
         {
            "station_id":"219",
            "name":"Central Square - East Boston",
            "short_name":"A32036",
            "lat":42.37454454514976,
            "lon":-71.03837549686432,
            "region_id":10,
            "rental_methods":[
               "KEY",
               "CREDITCARD"
            ],
            "capacity":19,
            "eightd_has_key_dispenser":false
         },
         {
            "station_id":"220",
            "name":"Test 1",
            "short_name":"Test 1",
            "lat":0,
            "lon":0,
            "rental_methods":[
               "KEY",
               "CREDITCARD"
            ],
            "capacity":0,
            "eightd_has_key_dispenser":false
         }
      ]
   }
};

var obj2 = {
   "last_updated":1493308075,
   "ttl":10,
   "data":{
      "stations":[
         {
            "station_id":"219",
            "num_bikes_available":7,
            "num_bikes_disabled":1,
            "num_docks_available":11,
            "num_docks_disabled":0,
            "is_installed":1,
            "is_renting":1,
            "is_returning":1,
            "last_reported":1493283725,
            "eightd_has_available_keys":false
         },
         {
            "station_id":"220",
            "num_bikes_available":0,
            "num_bikes_disabled":0,
            "num_docks_available":0,
            "num_docks_disabled":0,
            "is_installed":0,
            "is_renting":0,
            "is_returning":0,
            "last_reported":0,
            "eightd_has_available_keys":false
         }
      ]
   }
};


obj1.data.stations.forEach(function(item, i) {
 Object.assign(item, obj2.data.stations[i])
});

console.log(obj1)
Marcos Casagrande
  • 37,983
  • 8
  • 84
  • 98
  • This is great, it is exactly what I am looking for. What's about if I would like to support IE as well. It looks like IE does not support Object.assign. Thank you! – Giovanni Zambotti Apr 28 '17 at 18:07
  • @GiovanniZambotti The last part of my answer tells you what to do in browsers that do not support Object.assign or Array.find there are pollyfils, so you can use Object.assign in any browser. Don't forget to upvote/mark accepted answer if it worked. – Marcos Casagrande Apr 28 '17 at 18:21
  • Here's a direct link to the polyfill https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill – Marcos Casagrande Apr 28 '17 at 19:04
0

This code behaves like a join on the 2nd object (but can be extended to perform a full outer join)

It handles conflicts by appending a string _conflict to the key name

I've written this one to get you started but you'll have to customize it to support your exact structure

The combined object isn't a list anymore but has the same indexes as the array.

var obj1 = {  
   "conflicting_key":1493307962,
   "concurrent_key":10,
   "data":{  
      "listOfEvents":[ 
         {  
            "event_id":219,
            "name":"Central Square - East Boston",
            "rental_methods":[  
               "KEY",
               "CREDITCARD"
            ],
            "capacity":19
         },
         {  
            "event_id":220,
            "name":"Test 1",
            "lat":0,
            "lon":0,
            "rental_methods":[  
               "KEY",
               "CREDITCARD"
            ],
            "capacity":0,
            "eightd_has_key_dispenser":false
         }
      ]
   }
};

var obj2 = {  
   "conflicting_key":1493308075,
   "concurrent_key":10,
   "data":{  
      "listOfEvents":[
         {  
            "event_id":219,
            "num_bikes_available":7,
            "num_bikes_disabled":1,
            "last_reported":1493283725,
            "eightd_has_available_keys":false
         },
         {  
            "event_id":220,
            "num_bikes_available":0,
            "num_bikes_disabled":0,
            "num_docks_available":0,
            "is_returning":0,
            "last_reported":0,
            "eightd_has_available_keys":false
         }
      ]
   }
};

function combine(obj1, obj2) {
  var combinedObject = Object.assign({}, obj1);
  for(var key in obj2) {
    if(typeof obj2[key] !== "object") {
      if(obj1[key] !== obj2[key]) {
        var keyName = key;
        if(key in obj1) {
          keyName = keyName + "_conflict";
        }
        combinedObject[keyName] = obj2[key];
      }
    } else {
      combinedObject[key] = combine(obj1[key], obj2[key]);
    }
  }
  return combinedObject;
}

console.log(combine(obj1, obj2));
Gulfaraz Rahman
  • 417
  • 4
  • 13