Bhavin Padiya
Bhavin Padiya

Reputation: 87

Merge two JSON array on condition in Lodash

I have Two JSON Array Like:

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];    
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

Now, I want merged Like:

var c = [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

I know I can do it easily in plain JavaScript by the use of two for loop... But that takes n*n time.

I want to solve this problem in only n time.

How can I achieve that?

Upvotes: 0

Views: 3144

Answers (4)

ryeballar
ryeballar

Reputation: 30098

You can easily solve this by mapping the lesser sized array into a key-value composed object, where the keys of the object are the ids and their values are the associated values themselves. Once the association is accomplished, we can iterate and transform the greater sized array by assigning the missing values from the mapped object.

// ensure that b has more items than a
// to prevent data loss
if(a.length > b.length) {
  var t = b;
  b = a;
  a = t;
}

// create an object composed of of ids as key associated with each object.
// a loash alternative is: 
// var map = _.keys(a, '_id');
var map = a.reduce((r, v) => (r[v._id] = v, r), {});

// assign missing properties from each object from the associated mapped object.
var result = b.map(v => ({...map[v._id], ...v}));

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

// ensure that b has more items than a
// to prevent data loss
if(a.length > b.length) {
  var t = b;
  b = a;
  a = t;
}

// create an object composed of of ids as key associated with each object.
// a loash alternative is: 
// var map = _.keys(a, '_id');
var map = a.reduce((r, v) => (r[v._id] = v, r), {});

// assign missing properties from each object from the associated mapped object.
var result = b.map(v => ({...map[v._id], ...v}));

console.log(result);
.as-console-wrapper{min-height:100%;top:0}

Upvotes: 1

kailash yogeshwar
kailash yogeshwar

Reputation: 834

Hi there you can achieve it using below code

_.map(a, function (el){
   return _.merge(el , _.find(b, {_id: el._id }))
})

// using chain, i would prefer first it looks clean :-p
_.chain(a).map(function (o){
   return _.merge(o, _.find(b, {_id: o._id }))
})
.value()

I will try it with chain and update the answer

Upvotes: 0

Vivek
Vivek

Reputation: 1513

You should use lodash mergeWith function.

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];

var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];


// ouput [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

function customizer(firstValue, secondValue) {
  return Object.assign({}, firstValue, secondValue);
}

console.log(_.mergeWith(a, b, customizer));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

Upvotes: 2

CertainPerformance
CertainPerformance

Reputation: 370879

It's quite possible to achieve this in plain Javascript in O(n) time:

var a = [{_id:1, name: "Bhavin"},{_id:2, name: "Raj"},{_id:3, name: "Rahul"}];
var b = [{_id:1, post: "Developer"},{_id:2, post: "Quality Analyst"}];

const aById = a.reduce((map, { _id, name }) => map.set(_id, name), new Map());
const bById = b.reduce((map, { _id, post }) => map.set(_id, post), new Map());
const combined = [...aById.entries()].map(([_id, name]) => {
  const person = { _id, name };
  const post = bById.get(_id);
  if (post) person.post = post;
  return person;
});

console.log(combined);
var c = [{_id:1, name: "Bhavin", post: "Developer"},{_id:2, name: "Raj", post: "Quality Analyst"},{_id:3, name: "Rahul"}];

Maps are guaranteed to have O(1) lookup time. Object hashmaps (like {'1': 'Developer', '2': 'Quality Analyst'}) are not.

You had a couple of typos in your original code, I'm assuming those were unintentional - I fixed them in the snippet above.

Upvotes: 0

Related Questions