2016-07-27 16 views
15

私は1つの共通フィールドメンバーを持つ2つの配列を持っています。どのように簡単にテーマをマージできますか?例えばlodashを使ってオブジェクトの2つの配列をマージするには?

期待

var arr1 = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb") 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb") 
}]; 

var arr2 = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "name" : 'xxxxxx', 
    "age" : 25 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "name" : 'yyyyyyyyyy', 
    "age" : 26 
}]; 

var merge = [{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d6"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb"), 
    "name" : 'xxxxxx', 
    "age" : 25 
}, 
{ 
    "member" : ObjectId("57989cbe54cf5d2ce83ff9d8"), 
    "bank" : ObjectId("575b052ca6f66a5732749ecc"), 
    "country" : ObjectId("575b0523a6f66a5732749ecb"), 
    "name" : 'yyyyyyyyyy', 
    "age" : 26 
}]; 

私は

var merge = _.unionBy(arr1, arr2, 'member'); 

ではなく、EXPとして合併を試してみました影響を受けた。 アレイ1値を示します。誰も私を助けることができますか?

+1

http://youmightnotneedjquery.com/#deep_extendまたはhttp://youmightnotneedjquery.com/#extend、httpsにリンクしています: //lodash.com/docs#assign –

+1

私はあなたがこれを質問したことを覚えている[以前の質問](http://stackoverflow.com/questions/38505448/how-to-merge-multiple-array-of-object-by -id-in-javascript)と私は、最もupvoted答えが答えとして十分であったはずだと思う。 'memberID'を' member'で変更し、連結で 'arr3'と' arr4'を削除するだけです。 – ryeballar

+0

あなたが以前に得た答えは、あなたが実現する以上の宝石でした。それを2回投稿するように私に依頼しないでください。 – 4castle

答えて

23

両方の配列の順序が正しい場合。各項目は、関連付けられたメンバー識別子に対応し、次に簡単に使用できます。

の短いバージョンです
var merge = _.merge(arr1, arr2); 

var merge = _.chain(arr1).zip(arr2).map(function(item) { 
    return _.merge.apply(null, item); 
}).value(); 

あるいは、配列内のデータが特定の順序ではない場合、あなたはメンバー値によって関連付けられたアイテムを検索することができます。

var merge = _.map(arr1, function(item) { 
    return _.merge(item, _.find(arr2, { 'member' : item.member })); 
}); 

これは簡単にミックスインに変換できます。

_.mixin({ 
 
    'mergeByKey' : function(arr1, arr2, key) { 
 
    var criteria = {}; 
 
    criteria[key] = null; 
 
    return _.map(arr1, function(item) { 
 
     criteria[key] = item[key]; 
 
     return _.merge(item, _.find(arr2, criteria)); 
 
    }); 
 
    } 
 
}); 
 

 
var arr1 = [{ 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")', 
 
    "bank": 'ObjectId("575b052ca6f66a5732749ecc")', 
 
    "country": 'ObjectId("575b0523a6f66a5732749ecb")' 
 
}, { 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")', 
 
    "bank": 'ObjectId("575b052ca6f66a5732749ecc")', 
 
    "country": 'ObjectId("575b0523a6f66a5732749ecb")' 
 
}]; 
 

 
var arr2 = [{ 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d8")', 
 
    "name": 'yyyyyyyyyy', 
 
    "age": 26 
 
}, { 
 
    "member": 'ObjectId("57989cbe54cf5d2ce83ff9d6")', 
 
    "name": 'xxxxxx', 
 
    "age": 25 
 
}]; 
 

 
var arr3 = _.mergeByKey(arr1, arr2, 'member'); 
 

 
document.body.innerHTML = JSON.stringify(arr3, null, 4);
body { font-family: monospace; white-space: pre; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

+2

'_.map'の中で' _.find'を使用すると、O(n^2)の解決策が作成されます。 – 4castle

+1

この回答は、arr1に存在しないarr2の要素を除外します。 Ori Droriの答えを好む。 – joniba

+0

はまったく動作しません。両方のマージされた配列の代わりに最後の配列の値になります – phil1234

14

_.keyBy()merge辞書を使用して、両方のアレイに対して辞書を作成し、_.values()でアレイに結果を変換する:以下の例を参照してください。このように、配列の順序は関係ありません。さらに、異なる長さの配列を扱うこともできます。 ES6 Map

連結方式アレイ、及びMAPにreduce複合アレイを使用

const ObjectId = (id) => id; // mock of ObjectId 
 
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}]; 
 
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}]; 
 

 
const merged = _(arr1) // start sequence 
 
    .keyBy('member') // create a dictionary of the 1st array 
 
    .merge(_.keyBy(arr2, 'member')) // create a dictionary of the 2nd array, and merge it to the 1st 
 
    .values() // turn the combined dictionary to array 
 
    .value(); // get the value (array) out of the sequence 
 

 
console.log(merged);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.0/lodash.min.js"></script>

Object#assignを使用して、新しいオブジェクトに同じmemberのオブジェクトを結合し、マップに格納します。 Map#valuesspreadで配列にマップを変換します

const ObjectId = (id) => id; // mock of ObjectId 
 
const arr1 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"bank" : ObjectId("575b052ca6f66a5732749ecc"),"country" : ObjectId("575b0523a6f66a5732749ecb")}]; 
 
const arr2 = [{"member" : ObjectId("57989cbe54cf5d2ce83ff9d6"),"name" : 'xxxxxx',"age" : 25},{"member" : ObjectId("57989cbe54cf5d2ce83ff9d8"),"name" : 'yyyyyyyyyy',"age" : 26}]; 
 

 
const merged = [...arr1.concat(arr2).reduce((m, o) => 
 
    m.set(o.member, Object.assign(m.get(o.member) || {}, o)) 
 
, new Map()).values()]; 
 

 
console.log(merged);

+1

私はこれを好むでしょう – Seeker

+0

これはうまくいきませんが、最後の配列の内容だけを返すのです。 – phil1234

+0

@ phil1234 - 詳しく教えてください。両方のソリューション(lodashとwithout)は同じことを行い、同じ結果を持っています。類似のメンバーIDを持つ2つの配列のオブジェクトのプロパティをマージします。 –

関連する問題