I am wanting to merge the following object arrays, by first joining on the id property
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
},{
id: 2,
name: 'jim',
title: 'nobody'
},{
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
},{
id: 2,
wage: '10',
rate: 'hour'
},{
id: 3,
wage: '500',
rate: 'week'
}];
So the result would be
[{
id: 1,
name: 'fred',
title: 'boss',
wage: '300',
rate: 'day'
},{
id: 2,
name: 'jim',
title: 'nobody',
wage: '10',
rate: 'hour'
},{
id: 3,
name: 'bob',
title: 'dancer',
wage: '500',
rate: 'week'
}]
I would like to avoid using js frameworks (if possible), although ExtJs is already part of the project. AT the moment I have a loop with an inner loop that if the keys match it copies the properties and breaks out of the inner loop to start the next outer loop.
Any better suggestions?
I am wanting to merge the following object arrays, by first joining on the id property
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
},{
id: 2,
name: 'jim',
title: 'nobody'
},{
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
},{
id: 2,
wage: '10',
rate: 'hour'
},{
id: 3,
wage: '500',
rate: 'week'
}];
So the result would be
[{
id: 1,
name: 'fred',
title: 'boss',
wage: '300',
rate: 'day'
},{
id: 2,
name: 'jim',
title: 'nobody',
wage: '10',
rate: 'hour'
},{
id: 3,
name: 'bob',
title: 'dancer',
wage: '500',
rate: 'week'
}]
I would like to avoid using js frameworks (if possible), although ExtJs is already part of the project. AT the moment I have a loop with an inner loop that if the keys match it copies the properties and breaks out of the inner loop to start the next outer loop.
Any better suggestions?
Share Improve this question asked May 19, 2011 at 13:05 DavidDavid 8,6907 gold badges51 silver badges71 bronze badges 1-
This would be relatively easy to do with jQuery with the help of
.extend
-- anyhow, can you show the code you have so far, and does it work? Are you looking for an optimized solution? – Gary Green Commented May 19, 2011 at 13:30
3 Answers
Reset to default 4Like this?
var bined = [];
function findSecond(id,second){
for (var i=0;i<second.length;i++){
if(second[i].id === id){
return second[i];
}
}
return null
}
while (el = arr1.pop()){
var getSec = findSecond(el.id,arr2);
if (getSec){
for (var l in getSec){
if (!(l in el)) {
el[l] = getSec[l];
}
}
bined.push(el);
}
}
If the arrays have the same length, and the id's are equal, a simpler merge will do:
function merge(a1,a2) {
var i = -1;
while ((i = i+1)<a1.length) {
for (var l in a2[i]) {
if (!(l in a1[i] )) {
a1[i][l] = a2[i][l];
}
}
}
return a1;
}
Here's a working example
[Edit 2016/07/30] Added a snippet using more functional approach and, based on @djangos ment, an extra method to bine both arrays.
(function() {
var alert = function(str) {document.querySelector('#result').textContent += str + '\n';};
var arrays = getArrays();
alert('Combine on id (shared id\'s):')
alert(JSON.stringify(bineById(arrays.arr1, arrays.arr2), null, ' '));
alert('\nCombine on id (all id\'s):')
alert(JSON.stringify(bineBothById(arrays.arr1, arrays.arr2), null, ' '));
// for bineBothById the parameter order isn't relevant
alert('\nCombine on id (all id\'s, demo parameter order not relevant):')
alert(JSON.stringify(bineBothById(arrays.arr2, arrays.arr1), null, ' '));
// bine first array with second on mon id's
function bineById(arr1, arr2) {
return arr1.map(
function (el) {
var findInB = this.filter(function (x) {return x.id === el.id;});
if (findInB.length) {
var current = findInB[0];
for (var l in current) {
if (!el[l]) {el[l] = current[l];}
}
}
return el;
}, arr2);
}
// bine first array with second on all id's
function bineBothById(arr1, arr2) {
var bined = arr1.map(
function (el) {
var findInB = this.filter(function (x) {return x.id === el.id;});
if (findInB.length) {
var current = findInB[0];
for (var l in current) {
if (!el[l]) {el[l] = current[l];}
}
}
return el;
}, arr2);
bined = bined.concat(arr2.filter(
function (el) {
return !this.filter(function (x) {return x.id === el.id;}).length;
}, bined));
return bined;
}
function getArrays() {
return {
arr1: [{
id: 1,
name: 'fred',
title: 'boss'
}, {
id: 2,
name: 'jim',
title: 'nobody'
}, {
id: 3,
name: 'bob',
title: 'dancer'
}],
arr2: [{
id: 1,
wage: '300',
rate: 'day'
}, {
id: 2,
wage: '10',
rate: 'hour'
}, {
id: 4,
wage: '500',
rate: 'week'
}]
};
}
}());
<pre id="result"></pre>
You can merge two arrays by id column with Alasql library:
var res = alasql('SELECT * FROM ? arr1 JOIN ? arr2 USING id', [arr1,arr2]);
Try this example at jsFiddle.
try this...
var arr1 = [{
id: 1,
name: 'fred',
title: 'boss'
},{
id: 2,
name: 'jim',
title: 'nobody'
},{
id: 3,
name: 'bob',
title: 'dancer'
}];
var arr2 = [{
id: 1,
wage: '300',
rate: 'day'
},{
id: 2,
wage: '10',
rate: 'hour'
},{
id: 3,
wage: '500',
rate: 'week'
}];
let arr5 = arr1.map((item, i) => Object.assign({}, item, arr2[i]));
console.log(arr5)