Suavocado
Suavocado

Reputation: 969

Merging two multidimensional objects if they have the same key value in javascript

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

Answers (3)

Oka
Oka

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

unpollito
unpollito

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

pizzarob
pizzarob

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

Related Questions