2016-04-04 7 views
0

2番目のjsonで一致するstop_idが最初のjsonでサブ文書としてネストされるように2つのjsonファイルをマージしたいとします。jsonを別のjsonにサブ文書として結合する

これは私が何を意味するかです:

first.json:これは、駅を含むJSONファイルは、例えば、列車を停止しています。各フィールドにはstop_idフィールドがあります。 second.json

[ 
    { 
    "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 
    }] 

:これは、私は2番目にstop_id Sに一致する、という方法で、これらのドキュメントをマージしたい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 
    }] 

を経由して、駅に関連した旅行情報が含まれています。 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 - >オブジェクト)。旅行の場合も同様です – 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); 

再生するためのフィドル。 stop_idに一致するステーションのアレイで

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

trainsmapfilter

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

ここで第一JSONサンプルをstopstrips第二に格納されていると仮定すると、Array.prototype.map()を使用して少しワンライナーです。 (注意:オブジェクト拡張機能が必要です.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)})) 
関連する問題