dcp3450
dcp3450

Reputation: 11187

Efficient way to merge array of objects with similar data

I have two arrays that have a very large but unknown number of objects. For example:

const x = [
  {
    id:'apples',
    oldData: {
      min: 9,
      max: 50
    }
  },
  ...
]

const y = [
  {
    id:'bananas',
    newData: {
      min: 2,
      max: 60
    }
  },

  {
    id:'apples',
    newData: {
      min: 50,
      max: 200
    }
  },
  ...
]

I need to combine these so my result is something like:

const x = [
  {
    id:'apples',
    oldData: {
      min: 9,
      max: 50
    },
    newData: {
      min: 50,
      max: 200
    }
  },
  {
    id:'bananas',
    newData: {
      min: 2,
      max: 60
    }
  }
  ...
]

Note that apples is combined to include data from both arrays and bananas is add as a new element since it didn't have a match. Each array could have hundreds of values each so I found doing .map() and Object.keys().map() was really expensive.

Using ES6 and Lodash is imported.

Upvotes: 1

Views: 61

Answers (2)

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28455

You can try following

const x = [{id:'apples',oldData: {min: 9,max: 50}}];
const y = [{id:'bananas',newData: {min: 2,max: 60}},{id:'apples',newData: {min: 50,max: 200}}];

// Create an object with id as key and object as value
let obj = x.reduce((a,c) => Object.assign(a, {[c.id]:c}), {});
// Updating the value of object and adding new entries
y.forEach(v => {
  if(obj[v.id]) obj[v.id].newData = v.newData;
  else obj[v.id] = v;
});
// Getting the values in the object
console.log(Object.values(obj));

Upvotes: 1

Rafael
Rafael

Reputation: 7746

Creating a map is the way to go (one iteration per array):

const x = [ { id:'apples', oldData: { min: 9, max: 50 } } ];
const y = [
    { id:'bananas', newData: { min: 2,  max: 60  } },
    { id:'apples',  newData: { min: 50, max: 200 } }
];

let lookup = {};

//old
x.forEach(x_i => {
    lookup[x_i.id] = x_i;
});

//new
y.forEach(y_i => {
    if (y_i.id in lookup === false)
        lookup[y_i.id] = {};
    lookup[y_i.id].newData = y_i.newData;
});

console.log(lookup);

output:

{ apples:
   { id: 'apples',
     oldData: { min: 9, max: 50 },
     newData: { min: 50, max: 200 } },
  bananas: { newData: { min: 2, max: 60 } } }

Upvotes: 0

Related Questions