ey dee ey em
ey dee ey em

Reputation: 8623

How to use lodash intersectionWith to compare and find same attribute with same value among two arrays with difference structure?

for example, I have two set of arrays

arr1 = [
  {
    myName: 'Adam',
    mySkill: 'CSS',
  },
  {
    myName: 'Mutalib',
    mySkill: 'JavaScript',
  },
];

arr2 = [
  {
    myName: 'Adam',
    myWeight: '112',
  },
  {
    myName: 'Habib',
    myWeight: '221',
  },
];

I try to compare them, and pick the value of myName that is the same with lodash's intersectionWith function. But has not been able to by doing

newList.push(intersectionWith(arr1.arr2,isEqual])); 

*in this case, result of intersectionWith(arr1.arr2,isEqual]) should be Adam

Any suggestions, solutions, thoughts on how should I proceed further?

Also, previously I was using two forEach one within another to achieve that... unless that is the best way that I can do about this kind of sorting?

Upvotes: 5

Views: 13437

Answers (4)

awmidas
awmidas

Reputation: 683

We can do that without using lodash

const intersectionBy = (a, b, fn) => {
  const s = new Set(b.map(fn));
  return a.filter(x => s.has(fn(x)));
};

Example:

intersectionBy(arr1, arr2, x => x.myName);

Upvotes: 4

ryeballar
ryeballar

Reputation: 30118

You should use intersectionBy() to get the intersection by attribute.

var result = _.intersectionBy(arr1, arr2, 'myName');

var arr1 = [{
  myName: 'Adam',
  mySkill: 'CSS',
}, {
  myName: 'Mutalib',
  mySkill: 'JavaScript',
}];

var arr2 = [{
  myName: 'Adam',
  myWeight: '112',
}, {
  myName: 'Habib',
  myWeight: '221',
}];

var result = _.intersectionBy(arr1, arr2, 'myName');

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

If you want to extract the intersection with the myName value only then you can lazily evaluate it with intersectionBy() and map().

var result = _(arr1).intersectionBy(arr2, 'myName').map('myName').value();

var arr1 = [{
  myName: 'Adam',
  mySkill: 'CSS',
}, {
  myName: 'Mutalib',
  mySkill: 'JavaScript',
}];

var arr2 = [{
  myName: 'Adam',
  myWeight: '112',
}, {
  myName: 'Habib',
  myWeight: '221',
}];

var result = _(arr1).intersectionBy(arr2, 'myName').map('myName').value();

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>

Upvotes: 5

Redu
Redu

Reputation: 26191

I would like to develop a generic reusable solution for this. Lets define the objects with at least one common property holding the same value as Similar Objects. Then...

Object.prototype.isSimilar = function(o){ // return true if objects have at least one property with same value in common
  var ok = Object.keys(this);
  return typeof o === "object" ? ok.some(k => this[k] === o[k]) : false;
};
Array.prototype.containsSimilar = function(o){ // return true if it includes a similar object
  return this.some(e => typeof o === "object" ? o.isSimilar(e) : o === e);
};
Array.prototype.getSimilarObjects = function(...a) { // return similar objects in an array
  return [this,...a].reduce((p,c) => p.filter(e => c.containsSimilar(e)));
};

var arr1 = [
  {
    myName: 'Adam',
    mySkill: 'CSS',
  },
  {
    myName: 'Mutalib',
    mySkill: 'JavaScript',
  },
],

    arr2 = [
  {
    myName: 'Adam',
    myWeight: '112',
  },
  {
    myName: 'Habib',
    myWeight: '221',
  },
],
 result = arr1.getSimilarObjects(arr2);
console.log(JSON.stringify(result));

Upvotes: 0

kevin ternet
kevin ternet

Reputation: 4612

May I propose you this code which works well to solve your problem :

var jawn = arr1.map(v => v.myName).concat( arr2.map(v => v.myName)).sort().filter(function(item, pos, self) {
   return self.indexOf(item) != pos;
});

console.log(jawn);

Upvotes: 0

Related Questions