Reputation: 69
I have a problem merging two JSON objects, each from another array, into a new JSON object, in a new Array (the merging has to happen under given conditions).
Example:
First Array:
var array1 = [{box:123,name:xxx,amount:xxx},{box:321,....},...]
var array2 = [{_id:123,look:xxx,title:myBox1},{_id:321,.....},...]
var newArray = [{box:123,name:xxx,amount:xxx,look:xxx,title:myBox1},...]
What I basically need:
Iterate over Array1, iterate over Array2. If box (array1) == _id (array2)
merge all attributes from both objects into a new JSON and put it in the first free slot in a new array3.
I hope the example helps to see what I'm trying to do. What is the best solution?
Normally the first attribute in both arrays are also the ones that need to be compared, but it would be could, if the solution would work also if I want to compare e.g. 1st attribute in 1st array with 3rd attribute in 2nd array.
Hope someone can help me out!
Upvotes: 0
Views: 3863
Reputation: 2122
Creating the dummy datas, this is what the programming should be:
var a = [{
id: 1,
name: 'name1',
}, {
id: 2,
name: 'name2',
}, {
id: 3,
name: 'name3',
}];
var b = [{
id: 1,
look: 'look1'
}, {
id: 321,
look: 'look321'
}, {
id: 3,
look: 'look3',
}
];
// put the object id : 321 and look : look321 into array a from array b
for (var i = 0; i < b.length; i++) {
var obj_b= b[i];
var id_b= b[i].id;
var idNotFound = true;
a.forEach(function(rowOfA){
var id_a = rowOfA.id;
if(id_a == id_b ){
idNotFound = false;
}
});
if( idNotFound ){
a.push( b[i] );
}//if
}
// merge the objects with same ids into array a
for (var i = 0; i < a.length; i++) {
var id_a = a[i].id;
var found = false;
for (var j = 0; j < b.length; j++) {
var id_b= b[j].id;
if(id_a == id_b){
found = b[j];
}//if
}//for2
if (found) {
a[i]["look"] = found.look;
}//if
}//for1
console.log('aa=>',a);
/*
The output is aa=> [ { id: 1, name: 'name1', look: 'look1' },
{ id: 2, name: 'name2' },
{ id: 3, name: 'name3', look: 'look3' },
{ id: 321, look: 'look321' } ]
*/
Upvotes: 0
Reputation: 7
You can try this:
array3=[]
for(item1 in array1){
for(item2 in array2){
if(item1.box == item2._id)
array3.push(Merge_objects(item1,item2))
}
}
function Merge_objects(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
Upvotes: 0
Reputation: 2890
You could use Array.prototype.map or Array.prototype.reduce for that. And remember about time complexity! In case the objects are uniq by the key (_id
or box
) and arrays have equal lengths:
// TODO: implement your own comparator based on _id/box type
var first = array1.sort((a, b) => a._id - b._id);
var second = array2.sort((a, b) => a.box - b.box);
var merged = sorted_first.map((item, index) => Object.assign(item, second[index]));
You can easily adjust this to the different lengths case an so on, but you really need to know your data first.
Upvotes: 0
Reputation: 38345
The following function would do it. It's slightly longer than the other answers, but more generic (you can specify which of the properties are the ids, rather than sticking with box
and _id
) and doesn't modify the original arrays in any way. It's also not dependent on the order of the items in the two arrays being identical (i.e. box:123
can be in index 1 in array1, and _id:123
can be in index 3 in array2).
/*
a1 = the first array of objects
id1 = the name of the property of each object in a1 that is its id
a2 = the second array of objects
id2 = the name of the property of each object in a2 that is its id
*/
function combine(a1, id1, a2, id2) {
// create our new array to return
var newArray = []
// iterate over a1 (the outer loop)
for(var i = 0, l = a1.length; i < l; i++) {
var outer = a1[i]; // get the current object for this iteration
// iterate over a2 (the inner loop)
for(var j = 0, m = a2.length; j < m; j++) {
var inner = a2[j]; // get the current object for this iteration of the inner loop
if(outer[id1] == inner[id2]) { // compare the ids for the outer and inner objects
var o = {}; // create a new blank object to add to newArray
o[id1] = outer[id1]; // set its id (using the same property name as that of a1)
for(var prop in outer) { // iterate over properties
if(prop != id1) { // ignore the id property, but copy the others
o[prop] = outer[prop]
}
}
for(var prop in inner) {
if(prop != id2) {
o[prop] = inner[prop]
}
}
// add this object to newArray
newArray.push(o);
}
}
}
// return newArray
return newArray;
}
Usage:
var array1 = [{box:123,name:'Name 1',amount:1},{box:321,name:'Name 2',amount:2}]
var array2 = [{_id:123,look:'Look 1',title:'My box 1'},{_id:321,look:'Look 2',title:'My box 2'}]
var newArray = combine(array1, "box", array2, "_id");
Upvotes: 0
Reputation: 337560
You can achieve this with two loops. The first to iterate through the object stored in array1
and the second to iterate over the properties of the matching object in array2
. Try this:
var newArray = [];
for (var i = 0; i < array1.length; i++) {
var obj = array1[i];
if (array2[i] && obj.box == array2[i]._id) {
for (key in array2[i]) {
obj[key] = array2[i][key];
}
newArray.push(obj);
}
};
Upvotes: 1