2016-07-27 14 views
15

Mam dwie tablice z jednym wspólnym polu członek. jak mogę łatwo scalić motyw?Jak scalić dwie tablice obiektów za pomocą aplikacji lodash?

Na przykład:

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

Oczekiwany:

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

Próbowałem

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

ale nie połączyła się jako exp ect. pokazano wartość array1:. czy ktoś może mi pomóc?

+1

http://youmightnotneedjquery.com/#deep_extend lub http://youmightnotneedjquery.com/#extend, która łączy się od https: //lodash.com/docs#assign –

+1

Pamiętam, że zadałeś to pytanie [wcześniej] (http://stackoverflow.com/questions/38505448/how-to-merge-multiple-array-of-object-by -id-in-javascript) i uważam, że najbardziej przecząca odpowiedź powinna wystarczyć jako odpowiedź. Po prostu zmień 'memberID' na' member' i usuń 'arr3' i' arr4' w konkatenacji. – ryeballar

+0

Odpowiedź, którą otrzymałeś wcześniej, była bardziej klejnotem niż zdajesz sobie sprawę. Nie pytajcie nas, abyśmy dwukrotnie pisali, wystarczy zamknąć jako duplikat. – 4castle

Odpowiedz

23

Jeśli obie tablice są we właściwej kolejności; gdzie każdy element odpowiada przypisanemu identyfikatorowi członka, możesz go po prostu użyć.

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

który jest skróconą wersję:

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

Lub, jeśli dane w tablicach nie jest w określonej kolejności, można patrzeć powiązany obiekt przez wartość członkowskim.

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

Możesz łatwo przekonwertować to na mixin. Zobacz poniższy przykład:

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

Użycie '_.find' wewnątrz' _.map' tworzy rozwiązanie O (n^2). – 4castle

+1

Należy również zauważyć, że ta odpowiedź pominie elementy w arr2, które nie istnieją w arr1. Preferuj odpowiedź Ori Droriego. – joniba

+0

nie działa w ogóle, kończę z wartością ostatniej tablicy zamiast obu scalonych tablic – phil1234

14

Tworzenie słowników dla obu tablic używając _.keyBy(), merge słowników i przekonwertować wynik do tablicy z _.values(). W ten sposób kolejność tablic nie ma znaczenia. Ponadto może obsługiwać tablice o różnej długości.

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>

Stosując ES6 Map

łączą te tablice i reduce połączone tablicy na mapę. Użyj obiektu Object#assign, aby połączyć obiekty o tym samym numerze member z nowym obiektem i zapisać je na mapie. Konwersja mapę do tablicy z Map#values i 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

Wolałbym ten jeden – Seeker

+0

tak, ten działa, podczas gdy lodash zawodzi mizernie i zwraca tylko zawartość ostatniej tablicy – phil1234

+0

@ phil1234 - proszę rozwinąć. Oba moje rozwiązania (z lodash i bez) robią te same rzeczy i mają ten sam rezultat - łączenie właściwości obiektów w dwóch tablicach, które mają podobny identyfikator członka. –

Powiązane problemy