Reputation: 969
If I have two objects. How can I populate the first object with items of the second using values of the first as a key? Say that for the following example, I need the first object to contain all items from the second object with the same color as any of the first objects.
object1 = {
1:{
name:'bed',
color:'blue'
}
}
object2 = {
1:{
name:'chair',
color:'blue'
},
2:{
name:'table',
color:'red'
}
}
So this should result in
object1 = {
1:{
name:'bed',
color:'blue'
},
2:{
name:'chair',
color:'blue'
}
}
Upvotes: 3
Views: 1799
Reputation: 26355
Here's another solution that gets all objects from the second object, with colours that exist in any object in the first object.
Keep in mind that objects are passed around by reference, so you're working with shallow copies here.
Using objects instead of Arrays for these kinds of lists creates some key conflict headaches though, solved with manual indexing.
Note that your colour list is better served as a hashmap, instead of an Array, which reduces complexity in longer lists.
function colorMap (obj) {
var map = {};
Object.keys(obj).forEach(function (key) {
map[obj[key].color] = true;
});
return map;
}
function merge (one, two) {
var map = colorMap(one),
index = Object.keys(one).length;
Object.keys(two).forEach(function (key) {
if (map[two[key].color]) one[++index] = two[key];
});
return one;
}
//
var object1 = {
1:{
name:'bed',
color:'blue'
}
},
object2 = {
1:{
name:'chair',
color:'blue'
},
2:{
name:'table',
color:'red'
}
};
console.log(merge(object1, object2));
Upvotes: 1
Reputation: 1019
// Store all the colours in object1 inside an array
var colours = [];
var object1_keys = Object.keys(object1);
object1_keys.map(function(key)
{
if (colours.indexOf(object1[key].color) === -1)
{
colours.push(object1[key].color);
}
});
var last_index = object1_keys.length;
// Copy all the items from object2 into object1 if their colour
// is inside the colours array
var object2_keys = Object.keys(object2);
object2_keys.map(function(key)
{
if (colours.indexOf(object2[key].color) > -1)
{
last_index++;
object1[last_index] = object2[key];
}
});
Since you don't have an array, but an object with array-like indices, I'm using a variable called "last_index" to know the index that we need to set for the new items in object1. If you were using arrays, the logic would be simpler.
Edit: the main difference between my solution and realsenanp's is that he is merging the items for just one colour. If there were multiple colours in object1, the solution I propose would probably be more efficient.
Upvotes: 2
Reputation: 12029
Well here is something you can do. You specify which key and value you want to match..
var object1 = {
1:{
name:'bed',
color:'blue'
}
};
var object2 = {
1:{
name:'chair',
color:'blue'
},
2:{
name:'table',
color:'red'
}
};
// a - object1
// b - object2
// key - key you want to match
// value - value of key that must be matched
var mergeSameValue = function(a, b, key, value){
var count = 1;
for(var c in a){
if(a.hasOwnProperty(c)){
count ++;
}
}
for(var i in b){
if(b[i][key] === value){
a[count] = b[i]
count ++;
}
}
return a
};
// Your new object with both objects merged
var newObj = mergeSameValue(object1, object2, 'color', 'blue');
Upvotes: 1