Combine json arrays by key, javascript
Solution 1
If you wanted to write it so that you could take in any number of arrays, not just 2, you could utilize arguments, and do something like this:
var json1 = [{id:1,name:'aaa'},{id:5,name:'ccc'},{id:3,name:'bbb'}];
var json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'},
{id:1,parameter1:'u', parameter2:'v', parameter3:'w'},
{id:5,parameter1:'q', parameter2:'w', parameter3:'e'}];
function joinObjects() {
var idMap = {};
// Iterate over arguments
for(var i = 0; i < arguments.length; i++) {
// Iterate over individual argument arrays (aka json1, json2)
for(var j = 0; j < arguments[i].length; j++) {
var currentID = arguments[i][j]['id'];
if(!idMap[currentID]) {
idMap[currentID] = {};
}
// Iterate over properties of objects in arrays (aka id, name, etc.)
for(key in arguments[i][j]) {
idMap[currentID][key] = arguments[i][j][key];
}
}
}
// push properties of idMap into an array
var newArray = [];
for(property in idMap) {
newArray.push(idMap[property]);
}
return newArray;
}
var json3 = joinObjects(json1, json2);
console.log(JSON.stringify(json3));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution 2
Two one-liners:
with lodash:
res = _(json1).concat(json2).groupBy('id').map(_.spread(_.assign)).value();
in ES2015:
res = json2.map(x => Object.assign(x, json1.find(y => y.id == x.id)));
Solution 3
ES2015 georg's answer works great;
json1 = [
{id:1, test: 0},
{id:2, test: 0},
{id:3, test: 0},
{id:4, test: 0},
{id:5, test: 0}
];
json2 = [
{id:1, test: 1},
{id:3, test: 1},
{id:5, test: 1}
];
json1.map(x => Object.assign(x, json2.find(y => y.id == x.id)));
result:
{id:1, test: 1},
{id:2, test: 0},
{id:3, test: 1},
{id:4, test: 0},
{id:5, test: 1}
Solution 4
let json1 = [
{ id: 1, name: 'aaa' },
{ id: 5, name: 'ccc' },
{ id: 3, name: 'bbb' }
];
let json2 = [
{ id: 3, parameter1: 'x', parameter2: 'y', parameter3: 'z' },
{ id: 1, parameter1: 'u', parameter2: 'v', parameter3: 'w' },
{ id: 5, parameter1: 'q', parameter2: 'w', parameter3: 'e' }
];
let result = json1.map(obj => {
let data = json2.find(item => item.id === obj.id);
return {...obj, ...data}
});
console.log(result);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Solution 5
Use nested loops to find the corresponding elements and merge them.
for (var i = 0; i < json1.length; i++) {
var id = json1[i].id;
for (var j = 0; j < json2.length; j++) {
if (json2[j].id == id) {
for (var key in json2[j]) {
json1[i][key] = json2[j][key];
}
break;
}
}
}
At the end, json1
will contain the combined elements.
The above code assumes that every element of json2
matches something in json1
. If there can be extra elements in json2
, you'll need an additional loop afterward to copy those over to json1
.
user2083142
Updated on July 16, 2022Comments
-
user2083142 almost 2 years
I need to combine two json arrays, delivered by two rest services. The entries with the same "id" belong together.
json1 = [{id:1,name:'aaa'}, {id:5,name:'ccc'}, {id:3,name:'bbb'} ]; json2 = [{id:3,parameter1:'x', parameter2:'y', parameter3:'z'}, {id:1,parameter1:'u', parameter2:'v', parameter3:'w'}, {id:5,parameter1:'q', parameter2:'w', parameter3:'e'} ];
I need a combined/copied/cloned json array in javascript in the following way (my model in angular2):
json3 = [{id:3,name:'bbb',parameter1:'x', parameter2:'y', parameter3:'z'}, {id:1,name:'aaa', parameter1:'u', parameter2:'v', parameter3:'w'}, {id:5,name:'ccc', parameter1:'q', parameter2:'w', parameter3:'e'} ];
Is there a way to combine them? The parameter names are not defined exactly and it needs to work with variable parameter vectors.
I tried it with mixed for each loops. Seems to me very ugly.