2013-10-20 4 views
15

Javascriptで2つの配列をマージする正しい方法は何ですか?idでオブジェクトをマージするJavaScript

は、私は2つのアレイ(例えば)持っている:2つの配列は、上のベース接合されている

var a3 = [{ id : 1, name : "test", count : "1"}, 
      { id : 2, name : "test2", count : "2"}] 

var a1 = [{ id : 1, name : "test"}, { id : 2, name : "test2"}] 
var a2 = [{ id : 1, count : "1"}, {id : 2, count : "2"}] 

は、私のようなもので終わることができるようにしたいです'id'フィールドと余分なデータは単に追加されています。

私はこれを行うには_.unionを使用しようとしましたが、それは単にあなたがこの

function mergeObject(cake, icing) { 
    var icedCake = {}, ingredient; 
    for (ingredient in cake) 
     icedCake[ingredient] = cake[ingredient]; 
    for (ingredient in icing) 
     icedCake[ingredient] = icing[ingredient]; 
    return icedCake; 
} 

次のような単純なオブジェクトのマージ機能を書くことができます最初の1

+1

実際にやりたいことは、オブジェクトをマージすることです。 – JJJ

+0

構文が無効です。正当な例がありますか? –

+0

可能な複製http://stackoverflow.com/questions/1584370/how-to-merge-two-arrays-in-javascript –

答えて

29

これはトリックを行う必要があります。

var mergedList = _.map(a1, function(item){ 
    return _.extend(item, _.findWhere(a2, { id: item.id })); 
}); 

をこれは、A1における第二のオブジェクトのidが2ではなく「2」のIDを仮定すると、

+0

パーフェクト、thanks – Tam2

+1

a2がa1より多くの項目を配列に持つ場合、これは機能しません。 – CAOakley

+1

@ CAOakley - そうです。あなたはそれがうまくいかないと思いますか? –

0

に二番目の配列から値を上書きし、あなたも、あなたはまた、簡単なクローンとしてmergeObjectを使用することができます

var i, j, a3 = a1.slice(); 
for (i = 0; i < a2.length; ++i)    // for each item in a2 
    for (j = 0; i < a3.length; ++i)   // look at items in other array 
     if (a2[i]['id'] === a3[j]['id'])  // if matching id 
      a3[j] = mergeObject(a3[j], a2[i]); // merge 

あなたのデータstructreにそれを適用するには、二重ループを使用行う必要があります空のオブジェクトとして1つのパラメータを渡します。

11

が文字列であり、順序は重要ではありませんでなければならないことを前提としてい

  1. ハッシュテーブルを作成します。
  2. 両方の配列を繰り返し、ハッシュテーブルにIDでインデックスされたデータを格納します。そのIDを持つデータがすでにある場合は、Object.assign(ES6、polyfilled)に更新してください。
  3. ハッシュマップの値を持つ配列を取得します。 ECMAScript6で
var hash = Object.create(null); 
a1.concat(a2).forEach(function(obj) { 
    hash[obj.id] = Object.assign(hash[obj.id] || {}, obj); 
}); 
var a3 = Object.keys(hash).map(function(key) { 
    return hash[key]; 
}); 

、IDは必ずしも文字列でない場合、あなたはMapを使用することができます。

var hash = new Map(); 
a1.concat(a2).forEach(function(obj) { 
    hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj)) 
}); 
var a3 = Array.from(hash.values()); 
3

reduceバージョン。

var a3 = a1.concat(a2).reduce((acc, x) => { 
    acc[x.id] = Object.assign(acc[x.id] || {}, x); 
    return acc; 
}, {}); 
_.values(a3); 

私はそれが機能的な言語ではよくあることだと思います。

4

lodashの実装における:

var merged = _.map(a1, function(item) { 
    return _.assign(item, _.find(a2, ['id', item.id])); 
}); 

結果:

[ 
    { 
     "id":1, 
     "name":"test", 
     "count":"1" 
    }, 
    { 
     "id":2, 
     "name":"test2", 
     "count":"2" 
    } 
] 
1

は、すでに多くの偉大な答えがありますが、私はちょうど私が昨日解決するために必要な本当の問題からである別のものを追加します。

私はユーザIDを持つメッセージの配列と、ユーザの名前やその他の詳細を含むユーザの配列を持っていました。これは、私がユーザーの詳細をメッセージに追加する方法です。

var messages = [{userId: 2, content: "Salam"}, {userId: 5, content: "Hello"},{userId: 4, content: "Moi"}]; 
var users = [{id: 2, name: "Grace"}, {id: 4, name: "Janetta"},{id: 5, name: "Sara"}]; 

var messagesWithUserNames = messages.map((msg)=> { 
    var haveEqualId = (user) => user.id === msg.userId 
    var userWithEqualId= users.find(haveEqualId) 
    return Object.assign({}, msg, userWithEqualId) 
}) 
console.log(messagesWithUserNames) 
関連する問題