2016-07-27 9 views
15

Ich habe zwei Array mit einem gemeinsamen Feld Mitglied. Wie kann ich Theme einfach zusammenführen?Wie zwei Objektgruppen mit Hilfe von lodash zusammengeführt werden?

Zum Beispiel:

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 
}]; 

Erwartet:

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 
}]; 

I versucht

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

aber nicht als exp verschmolzen erreicht. gezeigt array1 Wert. Kann mir jemand helfen?

+1

http://youmightnotneedjquery.com/#deep_extend oder http://youmightnotneedjquery.com/#extend, die https Links: //lodash.com/docs#assign –

+1

Ich erinnere mich, dass Sie diese [Frage zuvor] (http://stackoverflow.com/questions/38505448/how-to-merge-multiple-array-of-object-by) gefragt haben -id-in-javascript) und ich denke, dass die meisten Antworten als Antwort ausreichen sollten. Ändern Sie einfach 'memberID' mit' member' und entfernen Sie 'arr3' und' arr4' in der Verkettung. – ryeballar

+0

Die Antwort, die Sie zuvor erhalten haben, war mehr ein Juwel als Sie erkennen. Bitten Sie uns nicht, es zweimal zu posten, schließen Sie es einfach als Duplikat. – 4castle

Antwort

23

Wenn beide Arrays in der richtigen Reihenfolge sind; wo jedes Element dem zugehörigen Mitgliedskennzeichen entspricht, können Sie einfach verwenden.

var merge = _.merge(arr1, arr2); 

, die die kurze Version ist:

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

Oder, wenn die Daten in den Feldern nicht in einer bestimmten Reihenfolge ist, können Sie das dazugehörige Element durch das Element Wert nachzuschlagen.

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

Sie können dies leicht zu einem Mixin konvertieren. Siehe nachstehendes Beispiel:

_.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

Mit '_.find' innerhalb' _.map' wird eine O (n^2) -Lösung erstellt. – 4castle

+1

Beachten Sie auch, dass bei dieser Antwort Elemente in arr2 ausgelassen werden, die in arr1 nicht vorhanden sind. Bevorzugen Ori Drori die Antwort. – joniba

+0

funktioniert überhaupt nicht, ich am Ende mit dem Wert des letzten Arrays anstelle von beiden gemischten Array – phil1234

14

erstellen Wörterbücher für beide Arrays _.keyBy(), merge die Wörterbücher, und konvertieren Sie das Ergebnis auf ein Array mit _.values(). Auf diese Weise spielt die Reihenfolge der Arrays keine Rolle. Darüber hinaus kann es auch Arrays unterschiedlicher Länge verarbeiten.

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>

ES6 Verwendung Map

Concat den Arrays und reduce die auf eine Karte kombinierten Arrays. Verwenden Sie Object#assign, um Objekte mit demselben member zu einem neuen Objekt zu kombinieren und in der Karte zu speichern. Konvertieren Sie die Karte auf ein Array mit Map#values und spread:

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

Ich würde dies eine – Seeker

+0

Yep dies funktioniert, während lodash kläglich scheitert und gibt nur den Inhalt des letzten Array zurück – phil1234

+0

@ phil1234 - bitte ausführlicher. Beide meiner Lösungen (mit lodash und ohne) tun die gleichen Dinge und haben das gleiche Ergebnis - die Eigenschaften von Objekten in den zwei Arrays, die eine ähnliche Mitglieds-ID haben, zusammenführen. –

Verwandte Themen