将json合并为另一个json作为子文档

时间:2016-04-04 11:40:13

标签: javascript json

我希望以第二个json中匹配stop_id的方式合并两个json文件,并将其嵌套为第一个json中的子文档。

这就是我的意思:

first.json :这是一个包含火车站点站点的json文件。每个都有一个stop_id字段。

[
  {
    "stop_id":70021,
    "stop_name":"CALTRAIN - 22ND ST STATION",
    "stop_lat":37.757692,
    "stop_lon":-122.392318,
    "zone_id":3329
  },
  {
    "stop_id":70022,
    "stop_name":"CALTRAIN - 22ND ST STATION",
    "stop_lat":37.757692,
    "stop_lon":-122.392318,
    "zone_id":3329
  },
  {
    "stop_id":70151,
    "stop_name":"CALTRAIN - ATHERTON STATION",
    "stop_lat":37.464458,
    "stop_lon":-122.198152,
    "zone_id":3331
  }]

second.json :这包含通过stop_id

与电台相关的旅行信息
[
  {
    "trip_id":"RTD8997283",
    "arrival_time":"05:40:00",
    "departure_time":"05:40:00",
    "stop_id":70021,
    "stop_sequence":1
  },
  {
    "trip_id":"RTD8997283",
    "arrival_time":"05:52:00",
    "departure_time":"05:52:00",
    "stop_id":70021,
    "stop_sequence":2
  },
  {
    "trip_id":"RTD8449096",
    "arrival_time":"07:33:00",
    "departure_time":"07:33:00",
    "stop_id":70022,
    "stop_sequence":1
  }]

我希望以一种方式合并这些文档,在second.json中匹配stop_id s嵌套在first.json中的stop_id文档下面。因此,例如,合并的最终结果将如下所示:

merged.json

[{
    "stop_id": 70021,
    "stop_name": "CALTRAIN - 22ND ST STATION",
    "stop_lat": 37.757692,
    "stop_lon": -122.392318,
    "zone_id": 3329,
    "trip": [{
        "trip_id": "RTD8997283",
        "arrival_time": "05:40:00",
        "departure_time": "05:40:00",
        "stop_id": 70021,
        "stop_sequence": 1
    }, {
        "trip_id": "RTD8997283",
        "arrival_time": "05:52:00",
        "departure_time": "05:52:00",
        "stop_id": 70021,
        "stop_sequence": 2
    }]
}, {
    "stop_id": 70022,
    "stop_name": "CALTRAIN - 22ND ST STATION",
    "stop_lat": 37.757692,
    "stop_lon": -122.392318,
    "zone_id": 3329,
    "trip": [{
        "trip_id": "RTD8449096",
        "arrival_time": "07:33:00",
        "departure_time": "07:33:00",
        "stop_id": 70022,
        "stop_sequence": 1
    }]
}, {
    "stop_id": 70151,
    "stop_name": "CALTRAIN - ATHERTON STATION",
    "stop_lat": 37.464458,
    "stop_lon": -122.198152,
    "zone_id": 3331
}]

对于大型数据集,是否可以通过javascript或任何其他方法进行此类合并?

6 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

var stnList = [{"stop_id": 70021,"stop_name": "CALTRAIN - 22ND ST STATION",  "stop_lat": 37.757692,"stop_lon": -122.392318,"zone_id": 3329}, {  "stop_id": 70022,  "stop_name": "CALTRAIN - 22ND ST STATION",  "stop_lat": 37.757692,  "stop_lon": -122.392318,  "zone_id": 3329}, {  "stop_id": 70151,  "stop_name": "CALTRAIN - ATHERTON STATION",  "stop_lat": 37.464458,  "stop_lon": -122.198152,  "zone_id": 3331}];

var travelList = [{  "trip_id": "RTD8997283",  "arrival_time": "05:40:00",  "departure_time": "05:40:00",  "stop_id": 70021,  "stop_sequence": 1}, {  "trip_id": "RTD8997283",  "arrival_time": "05:52:00",  "departure_time": "05:52:00",  "stop_id": 70021,  "stop_sequence": 2}, {  "trip_id": "RTD8449096",  "arrival_time": "07:33:00",  "departure_time": "07:33:00",  "stop_id": 70022,  "stop_sequence": 1}]

travelList.forEach(function(t) {
  // Find oobject
  var _stn = stnList.find(function(stn) {
    return stn.stop_id === t.stop_id
  });
  
  // check if trip property is defined or not
  if (!_stn.trip) _stn.trip = [];
  _stn.trip.push(t);
});

document.write("<pre>" + JSON.stringify(stnList, 0, 4) + "</pre>");

答案 1 :(得分:1)

在普通的Javascript中,您可以使用临时对象来引用目标项,并在另一个循环中推送所有行程。

此解决方案假设stop_id在两个数组中都匹配。

function merge(array1, array2) {
    var o = {};
    array1.forEach(function (a) {
        o[a.stop_id] = a;
    });
    array2.forEach(function (a) {
        o[a.stop_id].trip = o[a.stop_id].trip || [];
        o[a.stop_id].trip.push(a);
    });
}

var array1 = [{ "stop_id": 70021, "stop_name": "CALTRAIN - 22ND ST STATION", "stop_lat": 37.757692, "stop_lon": -122.392318, "zone_id": 3329 }, { "stop_id": 70022, "stop_name": "CALTRAIN - 22ND ST STATION", "stop_lat": 37.757692, "stop_lon": -122.392318, "zone_id": 3329 }, { "stop_id": 70151, "stop_name": "CALTRAIN - ATHERTON STATION", "stop_lat": 37.464458, "stop_lon": -122.198152, "zone_id": 3331 }],
    array2 = [{ "trip_id": "RTD8997283", "arrival_time": "05:40:00", "departure_time": "05:40:00", "stop_id": 70021, "stop_sequence": 1 }, { "trip_id": "RTD8997283", "arrival_time": "05:52:00", "departure_time": "05:52:00", "stop_id": 70021, "stop_sequence": 2 }, { "trip_id": "RTD8449096", "arrival_time": "07:33:00", "departure_time": "07:33:00", "stop_id": 70022, "stop_sequence": 1 }];

merge(array1, array2);
document.write('<pre>' + JSON.stringify(array1, 0, 4) + '</pre>');

答案 2 :(得分:1)

你可以array.forEach

first.forEach(function (val, index, theArray) {
   val.trip = [];
   second.forEach(function (val2, index, theArray) {
       if(val2.stop_id === val.stop_id){
           val.trip.push(val2);
       }
   });    
});

console.log(first);

玩弄小提琴。 https://jsfiddle.net/u3etdqrz/3/

答案 3 :(得分:1)

如果浏览器支持不是问题,Array.prototype.find可能是此案例的最佳解决方案。

for (let item1 of arr1) {
  item1.trip = arr2.find(item2 => item2.stopid === item1.stopid);
}

答案 4 :(得分:1)

假设第一个JSON样本存储在Array.prototype.map()中,第二个JSON样本存储在stops中,则使用trips进行一次单行调换。 (警告:它需要一个对象扩展函数。我使用了jQuery&#39; $.extend(),但任何对象扩展方法都可行,例如Underscore / Lodash&#39; s _.extend()或Node.js&#39 ; s util._extend。)

var merged = stops.map(function(stop){ return $.extend({}, stop, {trip: trips.filter(function(trip) { return trip.stop_id === stop.stop_id; })}); })

如果你喜欢ES6's arrow functions,你可以让它更漂亮一点:

var merged = stops.map(stop=>$.extend({}, stop, {trip: trips.filter(trip => trip.stop_id === stop.stop_id)}))

这两个都会保持原始数组不变,但是如果您只想将旅行合并到停靠点并且您不关心保留原始数据,则可以删除$.extend()的第一个参数;这样效率更高(特别是对于非常大的数据集),您不必担心将其保存在变量中:

stops.map(stop=>$.extend(stop, {trip: trips.filter(trip => trip.stop_id === stop.stop_id)}))

答案 5 :(得分:0)

在匹配map的电台数组中,{p> trains超过filterstop_id

function getStations(stations, id) {
  return stations.filter(function(obj) {
    return obj.stop_id === id;
  });
}

function mergeInfo(trains, stations) {
  return trains.map(function(obj) {
    var filtered = getStations(stations, obj.stop_id);
    if (filtered.length) obj.trip = filtered;
    return obj;
  });
}

var output = mergeInfo(trains, stations);

DEMO