Reputation: 450
I have the following json array:
array 1:
fruits1 = [{"fruit":"banana","amount":"2","color":"yellow"},{"fruit":"apple","amount":"5","color":"red"},{"fruit":"kiwi","amount":"1","color":"green"}]
array 2:
fruits2 = [{"fruit":"banana","sold":"1","stock":"3"},{"fruit":"apple","sold":"3","stock":"5"},{"fruit":"kiwi","sold":"2","stock":"3"}]
I would like to get just one array which has the results merged according to the fruits value like this:
fruits = [{"fruit":"banana","amount":"2","color":"yellow","sold":"1","stock":"3"},{"fruit":"apple","amount":"5","color":"red","sold":"3","stock":"5"},{"fruit":"kiwi","amount":"1","color":"green","sold":"2","stock":"3"}]
I need to do something like
foreach item.fruit where fruit = fruit from initial array
fruits.push item
Any idea?
Upvotes: 0
Views: 228
Reputation: 3979
Here's a generic way that works with your data:
function joinObjects(initial, other, predicate, valueSelector) {
if(typeof(predicate) !== 'function') throw 'predicate must be a function';
if(typeof(valueSelector) !== 'function') throw 'valueSelector must be a function';
// make a clone of the original object so its not modified
var clone = jQuery.extend(true, {}, initial);
// iterate over the initial and other collections
for(var cloneKey in clone) {
if (!clone.hasOwnProperty(cloneKey)) continue;
for(var otherKey in other) {
if (!other.hasOwnProperty(otherKey)) continue;
// if the predicate is truthy, get the values
if (predicate(clone[cloneKey], other[otherKey])) {
// pull only the values you want to merge
var values = valueSelector(other[otherKey]);
// iterate over the values add them to the cloned initial object
for(var valueKey in values) {
if (values.hasOwnProperty(valueKey)) {
clone[cloneKey][valueKey] = values[valueKey];
}
}
}
}
}
return clone;
}
var fruits1 = [{"fruit":"banana","amount":"2","color":"yellow"},{"fruit":"apple","amount":"5","color":"red"},{"fruit":"kiwi","amount":"1","color":"green"}];
var fruits2 = [{"fruit":"banana","sold":"1","stock":"3"},{"fruit":"apple","sold":"3","stock":"5"},{"fruit":"kiwi","sold":"2","stock":"3"}];
var finalFruits = joinObjects(fruits1, fruits2,
function(left, right) { return left.fruit == right.fruit },
function(other) {
return {
sold: other.sold,
stock: other.stock
};
});
console.log(finalFruits);
Upvotes: 0
Reputation: 4870
Try this logic:
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
var obj1 = [];
for (var i = 0; i < fruits1.length ; i++) {
obj1[fruits1[i].fruit] = fruits1[i];
}
var obj2 = [];
for (var i = 0; i < fruits2.length ; i++) {
obj2[fruits2[i].fruit] = fruits2[i];
}
var fruits = []
for (var key in obj1) {
fruits.push(merge_options(obj1[key],obj2[key]));
}
console.log(fruits);
Upvotes: 1
Reputation: 2099
You can do something like this with javascript
// create a hash like {fruit_name -> object}
f1 = {};
fruits1.forEach(function(p) {
f1[p.fruit] = p;
});
// merge second array into above hash on fruit_name
fruits2.forEach(function(p) {
for (var a in p) { f1[p.fruit][a] = p[a];}
});
//fruits1 will now contain result;
//if you don't want to spoil fruit1 array, clone p inside 'fruits1.forEach' above before assigning it to 'f1[p.fruit]'. And at the end, create a new array out of f1
Upvotes: 0