2013-10-20 2 views
15

두 개의 배열을 자바에서 병합하는 올바른 방법은 무엇입니까?id로 객체 병합 JavaScript

가 나는 두 개의 배열 (예를 들어)이있어 : 두 배열을 기반으로 결합되고있다

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

그래서 실제로 수행하려는 것은 개체를 병합하는 것입니다. – JJJ

+0

구문이 유효하지 않습니다. 합법적 인 예가 있습니까? –

+0

가능한 복제 http://stackoverflow.com/questions/1584370/how-to-merge-two-arrays-in-javascript –

답변

29

이 트릭을 수행해야합니다 오히려 "2"

+0

Perfect , thanks – Tam2

+1

a2가 a1보다 배열에 더 많은 항목을 가지고 있다면 이것은 작동하지 않을 것입니다. – CAOakley

+1

@ CAOakley - 가능합니다. 그게 효과가 없다고 생각하는 이유는 무엇입니까? –

0

에 제 2 어레이로부터의 값을 덮어 당신도, 당신은 또한 단순한 복제로 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에 적용 더블 루프를 사용 할 필요가 하나의 매개 변수를 빈 객체로 전달합니다.

11

가정 ID를 문자열과 순서는 중요하지 않습니다보다

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

이 A1에서 두 번째 개체의 ID가 있어야합니다 가정합니다 (2) , 할 수 있습니다

  1. 해시 테이블을 만듭니다.
  2. 두 배열을 반복하고 ID로 인덱싱 된 해시 테이블에 데이터를 저장합니다. 이미 ID가있는 데이터가있는 경우 Object.assign (ES6, polyfilled 일 수 있음)으로 업데이트하십시오.
  3. 해시 맵의 값을 가진 배열을 가져옵니다. IDS는 문자열이 필요하지 않은 경우 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]; 
}); 

, 당신은 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 implementaiton :

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)