2017-12-08 18 views
3

オブジェクトの2つの配列をマージします。キーは同じですが、値が必ずしも同じではない場合があります。同じキーを持つオブジェクトの2つの配列をマージしますが、一部のオブジェクトは同じ値を持たないでしょうか?

すべての解決策はjavascriptでお勧めできますが、Pythonソリューションでも問題はありません。ここで

はサンプルデータです:

var g= [ 
    { id: 36, name: 'AAA', goal: 'yes' , 'random':27}, 
    { id: 40, name: 'BBB', goal: 'yes' }, 
    { id: 39, name: 'JJJ', goal: 'yes' }, 
    { id: 27, name: 'CCC', goal: 'yes' , lag: "23.3343"}]; 


var c= [ 
    { id: 36, name: 'AAA', goal: 'yes', color:"purple" }, 
    { id: 40, name: 'BBB', circle: 'yes', color:"purple" }, 
    { id: 100, name: 'JJJ', circle: 'yes'} ]; 

私の予想出力は次のようになります。

var finalData = [{ 
{ id: 36, name: 'AAA', goal: 'yes' ,'random':27, color:"purple"}, 
{ id: 40, name: 'BBB', circle: 'yes', color:"purple"}, 
{ id: 39, name: 'JJJ', goal: 'yes' }, 
{ id: 27, name: 'CCC', goal: 'yes' ,lag: "23.3343"}, 
{ id: 100, name: 'JJJ', circle: 'yes' } 

    }] 

ここに私の現在のコードで、「それはある程度動作しますが、それはdoesnの削除したキーを追加しないでください。

var finalData = []; 
for(var i in g){ 
    var shared = false; 
    for (var j in c) 
     if (c[j].name == g[i].name) { 
      shared = true; 
      break; 
     } 
    if(!shared) finalData.push(g[i]) 
} 
finalData = finalData.concat(c); 

finalData 
+0

「キー」には「ゴール」と同じキーがありますか? – Nishant

+0

[オブジェクトの2つの配列をマージする]の可能な複製(https://stackoverflow.com/questions/7146217/merge-2-arrays-of-objects) – Nishant

答えて

1

ここにPythonソリューションがあります。これにより、gが変更される可能性があります。

c_by_id = {d['id']: d for d in c} 
for item in g: 
    item.update(c_by_id.get(item['id']), {}) 
+1

OPはJavaScriptソリューションを望んでいると私は思っています。 – 31piy

2

あなたは独立したオブジェクトを作成するために、同じオブジェクトとObject.assignで同じidを保つためMapを使用することができます。

var g = [{ id: 36, name: 'AAA', goal: 'yes', 'random': 27 }, { id: 40, name: 'BBB', goal: 'yes' }, { id: 39, name: 'JJJ', goal: 'yes' }, { id: 27, name: 'CCC', goal: 'yes', lag: "23.3343" }], 
 
    c = [{ id: 36, name: 'AAA', goal: 'yes', color: "purple" }, { id: 40, name: 'BBB', circle: 'yes', color: "purple" }, { id: 100, name: 'JJJ', circle: 'yes' }], 
 
    map = new Map, 
 
    result = g.concat(c).reduce(function (r, o) { 
 
     var temp; 
 
     if (map.has(o.id)) { 
 
      Object.assign(map.get(o.id), o); 
 
     } else { 
 
      temp = Object.assign({}, o); 
 
      map.set(temp.id, temp); 
 
      r.push(temp); 
 
     } 
 
     return r; 
 
    }, []); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

削減なしと連結なしバージョン。

function merge(o) { 
 
    var temp; 
 
    if (map.has(o.id)) { 
 
     Object.assign(map.get(o.id), o); 
 
     return; 
 
    } 
 
    temp = Object.assign({}, o); 
 
    map.set(temp.id, temp); 
 
    result.push(temp); 
 
} 
 

 
var g = [{ id: 36, name: 'AAA', goal: 'yes', 'random': 27 }, { id: 40, name: 'BBB', goal: 'yes' }, { id: 39, name: 'JJJ', goal: 'yes' }, { id: 27, name: 'CCC', goal: 'yes', lag: "23.3343" }], 
 
    c = [{ id: 36, name: 'AAA', goal: 'yes', color: "purple" }, { id: 40, name: 'BBB', circle: 'yes', color: "purple" }, { id: 100, name: 'JJJ', circle: 'yes' }], 
 
    map = new Map, 
 
    result = []; 
 

 
[g, c].forEach(function (a) { 
 
    a.forEach(merge); 
 
}); 
 

 
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

+0

rが配列ではないため、r.push(temp)が何をするか説明できますか?また、私は大きなデータセットでこのソリューションを試したときに、ループしたすべてのオブジェクトではなく、最後のオブジェクトだけを返します。 reduceは単一の値を返すだけなので、私は考えています。私はマップを使って減らしましたが、どちらもうまくいきませんでした。 – Sayran

+0

'r'はreduceコールバックからの累計です。初期値として空の配列を持ちます。 –

+0

大きなデータセットでこの解決策を試したとき、ループしたすべてのオブジェクトの代わりに最後のオブジェクトのみが返されます。 reduceは単一の値を返すだけなので、私は考えています。私はマップを使ってreduceを切り替えましたが、どちらもうまくいきません – Sayran

1

これは容易に下線機能_.uniq_.unionによって達成することができます。

ただ、この使用:これは、あなたが探しているものに戻ります

var finalData = _.uniq(_.union(c, g), function (ele) { 
        return ele.id 
       }) 

を。

関連する問題