2016-04-04 32 views
0

我想合并两个json文件,第二个json中的匹配stop_id作为子文档嵌套在第一个json中。将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 
    }] 

我想要的方式,合并这些文件,在第二匹配stop_id秒。 json嵌套在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或任何其他方式做这样的合并,对于大型数据集?

+0

如果数据集很大,则可能需要先将对象数组转换为一个映射(stopid - > object)用于更快速查找。同样对于旅行 – gurvinder372

+0

你在服务器或客户端上工作吗? – Yoda

+0

您是否特意在javascript中执行此操作,或者像'jq'命令行工具一样适合您的目的? –

回答

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/

+0

为什么'.slice()'?你已经在编辑了,为什么麻烦在内存中复制数组? –

+0

@KenB:同意你是对的,可能我不确定他在工作的环境......只是为了保证安全... – Thalaivar

+0

'slice()'只是浅拷贝数组本身,而不是它的内容;你仍然在内部采取相同的对象,你似乎明白了,因为你是'console.log()'末尾的原始数组 –

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>");

+0

会试一试。感谢您的快速响应 – Rexford

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>');

+0

感谢您的快速响应。会试试看。答案中有很多不同的方法。将尝试所有 – Rexford

0

map超过匹配stop_id该站的阵列中trainsfilter

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

+1

会试一试。感谢您的快速响应 – Rexford

1

如果浏览器的支持是没有问题的,Array.prototype.find可能是这种情况下,最好的解决办法。

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

下面是使用Array.prototype.map(),假设第一JSON样本被存储在stopstrips第二一点单行。 (注意:它需要一个对象扩展函数,我使用jQuery的$.extend(),但任何对象扩展方法都可以使用,例如Underscore/Lodash的_.extend()或Node.js的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)})) 
相关问题