[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 일 편집 :
내 초기 솔루션 이후 편집으로 인해 컨텍스트가 변경됨에 따라. 현재 기준과 일치하도록 솔루션을 업데이트하고 싶습니다. 즉,
-
중복 객체를 생성하지 않고 배열 객체를 병합하고,
-
속성이 이전 배열에 이미 있는
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'}]