[javascript] 2 개의 객체 배열 병합

예를 살펴 보겠습니다.

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

이 두 개체 배열을 병합하고 다음 배열을 만들어야합니다.

arr3 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'});

이를 수행하는 JavaScript 또는 jQuery 함수가 있습니까?

$.extend나에게 적합하지 않습니다. 그것은 반환

arr4 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});



답변

JavaScript에서 두 개의 객체 배열을 병합하려는 경우. 이 한 줄 트릭을 사용할 수 있습니다.

Array.prototype.push.apply(arr1,arr2);

예를 들어

var arr1 = [{name: "lang", value: "English"},{name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

Array.prototype.push.apply(arr1,arr2);

console.log(arr1);  // final merged result will be in arr1

산출:

[{"name":"lang","value":"English"},
{"name":"age","value":"18"},
{"name":"childs","value":"5"},
{"name":"lang","value":"German"}]


답변

ES6를 사용하면 아래와 같이 매우 쉽게 할 수 있습니다.

var arr1 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = [...arr1, ...arr2];

산출:

    arr3 = [
      {"name":"lang","value":"German"},
      {"name":"age","value":"18"},
      {"name":"childs","value":"5"},
      {"name":"lang","value":"German"}
    ]


답변

현대적인 것을 실험하는 사람들을 위해 :

var odd = [
    { name : "1", arr: "in odd" },
    { name : "3", arr: "in odd" }
];

var even = [
    { name : "1", arr: "in even" },
    { name : "2", arr: "in even" },
    { name : "4", arr: "in even" }
];

// ----
// ES5 using Array.filter and Array.find
function merge(a, b, prop){
  var reduced = a.filter(function(aitem){
      return ! b.find(function(bitem){
          return aitem[prop] === bitem[prop];
      });
  });
  return reduced.concat(b);
}
console.log( "ES5", merge(odd, even, "name") );

// ----
// ES6 arrow functions
function merge(a, b, prop){
    var reduced =  a.filter( aitem => ! b.find ( bitem => aitem[prop] === bitem[prop]) )
  return reduced.concat(b);
}
console.log( "ES6", merge(odd, even, "name") );

// ----
// ES6 one-liner
var merge = (a, b, p) => a.filter( aa => ! b.find ( bb => aa[p] === bb[p]) ).concat(b);


console.log( "ES6 one-liner", merge(odd, even, "name") );

// Results
// ( stuff in the "b" array replaces things in the "a" array )
// [
//    {
//         "name": "3",
//         "arr": "in odd"
//     },
//     {
//         "name": "1",
//         "arr": "in even"
//     },
//     {
//         "name": "2",
//         "arr": "in even"
//     },
//     {
//         "name": "4",
//         "arr": "in even"
//     }
// ]


답변

업데이트 2019 년 10 월 12 일

새로운 자바 스크립트만을 기반으로하고 타사 라이브러리가 필요없는 새 버전입니다.

const mergeByProperty = (target, source, prop) => {
  source.forEach(sourceElement => {
    let targetElement = target.find(targetElement => {
      return sourceElement[prop] === targetElement[prop];
    })
    targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
  })
}
var target /* arr1 */ = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var source /* arr2 */ = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

mergeByProperty(target, source, 'name');

console.log(target)

이 대답은 점점 늙어 가고 있었고 lodash 및 underscore와 같은 libs는 요즘 훨씬 덜 필요합니다. 이 새 버전에서 대상 (arr1) 배열은 우리가 작업하고 있으며 최신 상태로 유지하려는 배열입니다. 소스 (arr2) 배열은 새 데이터 의 출처 이며 대상 배열에 병합하려고합니다 .

우리 오버 루프 소스 새 데이터를 찾고 배열, 아직 우리에없는 모든 개체에 대한 대상 배열 우리는 단순히 그 객체 사용하여 추가 target.push (sourceElement)
우리를 기반으로하는 경우, 키 속성 ( ‘이름’) , object는 이미 대상 배열에 있습니다. Object.assign (targetElement, sourceElement)를 사용하여 속성과 값을 업데이트합니다 . 우리의“타겟”은 항상 동일한 배열이며 업데이트 된 내용을 포함합니다.


밑줄 또는 lodash를 사용하는 이전 답변

나는 항상 Google에서 여기에 도착하고 항상 답변에 만족하지 않습니다. 대답은 좋지만 underscore.js를 사용하면 더 쉽고 깔끔 할 것입니다.

데모 : http://jsfiddle.net/guya/eAWKR/

다음은 객체의 속성을 사용하여 2 개의 배열을 병합하는보다 일반적인 함수입니다. 이 경우 속성은 ‘이름’입니다.

var arr1 = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

function mergeByProperty(arr1, arr2, prop) {
  _.each(arr2, function(arr2obj) {
    var arr1obj = _.find(arr1, function(arr1obj) {
      return arr1obj[prop] === arr2obj[prop];
    });

    arr1obj ? _.extend(arr1obj, arr2obj) : arr1.push(arr2obj);
  });
}

mergeByProperty(arr1, arr2, 'name');

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

[{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]


답변

var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr1[i])
}
arr3 = arr3.concat(arr2);

여기에 이미지 설명 입력


답변

ES6 스프레드 연산자를 사용하면 매우 간단합니다.

const array1 = [{a: 'HI!'}, {b: 'HOW'}]
const array2 = [{c: 'ARE'}, {d: 'YOU?'}]

const mergedArray = [ ...array1, ...array2 ]
console.log('Merged Array: ', mergedArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Merged Array: [ {a: 'HI!'}, {b: 'HOW'} {c: 'ARE'}, {d: 'YOU?'} ]

참고 : 위의 솔루션은 ES6 스프레드 연산자를 사용하여 두 배열을 병합하는 것입니다.

@ bh4r4th에 의해 2020 년 1 월 7 일 편집 :
내 초기 솔루션 이후 편집으로 인해 컨텍스트가 변경됨에 따라. 현재 기준과 일치하도록 솔루션을 업데이트하고 싶습니다. 즉,

  1. 중복 객체를 생성하지 않고 배열 객체를 병합하고,

  2. 속성이 이전 배열에 이미 있는 value경우 업데이트name

const arr1 = [
    { name: "lang", value: "English" },
    { name: "age", value: "18" }
]
const arr2 = [
    { name: "childs", value: '2' },
    { name: "lang", value: "German" }
]
const arr3 = [
    { name: "lang", value: "German" },
    { name: "age", value: "28" },
    { name: "childs", value: '5' }
]

// Convert to key value dictionary or object
const convertToKeyValueDict = arrayObj => {
    const val = {}
    arrayObj.forEach(ob => {
        val[ob.name] = ob.value
    })
    return val
}

// update or merge array
const updateOrMerge = (a1, a2) => {
    const ob1 = convertToKeyValueDict(a1)
    const ob2 = convertToKeyValueDict(a2)
    // Note: Spread operator with objects used here
    const merged_obj = {...ob1, ...ob2}
    const val = Object.entries(merged_obj)
    return val.map(obj => ({ name: obj[0], value: obj[1] }))
}

const v1 = updateOrMerge(arr1, arr2)
const v2 = updateOrMerge(v1, arr3)
console.log(`Merged array1 and array2: ${JSON.stringify(v1)} \n\n`)
console.log(`Merged above response and array3: ${JSON.stringify(v2)} \n\n`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


답변

두 배열 병합 :

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var result=arr1.concat(arr2);
// result: [{name: "lang", value: "English"}, {name: "age", value: "18"}, {name : "childs", value: '5'}, {name: "lang", value: "German"}]

‘name’에 대한 중복 값없이 두 배열 병합 :

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var i,p,obj={},result=[];
for(i=0;i<arr1.length;i++)obj[arr1[i].name]=arr1[i].value;
for(i=0;i<arr2.length;i++)obj[arr2[i].name]=arr2[i].value;
for(p in obj)if(obj.hasOwnProperty(p))result.push({name:p,value:obj[p]});
// result: [{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]