2016-04-04 55 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)})) 
相關問題