14

I need some help. How can I get the array of the difference on this scenario:

var b1 = [
  { id: 0, name: 'john' }, 
  { id: 1, name: 'mary' }, 
  { id: 2, name: 'pablo' }, 
  { id: 3, name: 'escobar' } 
]; 

var b2 = [
  { id: 0, name: 'john' }, 
  { id: 1, name: 'mary' }
];

I want the array of difference:

// [{ id: 2, name: 'pablo' }, { id: 3, name: 'escobar' }]

How is the most optimized approach?

I´m trying to filter a reduced array.. something on this line:

var Bfiltered = b1.filter(function (x) {
return x.name !== b2.reduce(function (acc, document, index) {
    return (document.name === x.name) ? document.name : false
},0)

});

console.log("Bfiltered", Bfiltered);
// returns { id: 0, name: 'john' }, { id: 2, name: 'pablo' }, { id: 3, name: 'escobar' } ]

Thanks,

Robot

RobotMan
  • 171
  • 1
  • 1
  • 5
  • 1
    Not sure why you are getting down voted as your question has been updated to reflect a well formatted post, +1 from me. – Ryan Wilson Jun 01 '18 at 17:17
  • @RyanWilson so you are one of those people who upvotes average O(m\*n) solutions for problems that are O(max(m, n)) at best and questions that have been asked a million times before (though admittedly with O(m\*n) solutions at the top aswell) – ASDFGerte Jun 01 '18 at 17:36
  • 1
    @ASDFGerte I'm one of those people who appreciates a person's willingness to learn and who is attempting to solve a programming problem. – Ryan Wilson Jun 01 '18 at 17:38
  • @RyanWilson Google probably remembered my past searches, but the duplicate link i gave was the first result given when copying this question's title in, without changing a single letter. – ASDFGerte Jun 01 '18 at 17:43
  • 1
    @ASDFGerte While I agree this could have been searched better by the OP, they are obviously some what new to this site and I tend to cut the new people more slack then someone who has been coming to this site for a long time. I guess I'm one of those "softies" who likes to encourage people rather than criticize. – Ryan Wilson Jun 01 '18 at 17:45

3 Answers3

40

.Filter() and .some() functions will do the trick

var b1 = [
  { id: 0, name: 'john' }, 
  { id: 1, name: 'mary' }, 
  { id: 2, name: 'pablo' }, 
  { id: 3, name: 'escobar' } 
]; 

var b2 = [
  { id: 0, name: 'john' }, 
  { id: 1, name: 'mary' }
];

var res = b1.filter(item1 => 
!b2.some(item2 => (item2.id === item1.id && item2.name === item1.name)))

console.log(res);
Chiller
  • 9,520
  • 2
  • 28
  • 38
8

You can use filter to filter/loop thru the array and some to check if id exist on array 2

var b1 = [{ id: 0, name: 'john' }, { id: 1, name: 'mary' }, { id: 2, name: 'pablo' }, { id: 3, name: 'escobar' } ]; 
var b2 = [{ id: 0, name: 'john' }, { id: 1, name: 'mary' }];

var result = b1.filter(o => !b2.some(v => v.id === o.id));

console.log(result);

Above example will work if array 1 is longer. If you dont know which one is longer you can use sort to arrange the array and use reduce and filter.

var b1 = [{ id: 0, name: 'john' }, { id: 1, name: 'mary' }, { id: 2, name: 'pablo' }, { id: 3, name: 'escobar' } ]; 
var b2 = [{ id: 0, name: 'john' }, { id: 1, name: 'mary' }];

var result = [b1, b2].sort((a,b)=> b.length - a.length)
                     .reduce((a,b)=>a.filter(o => !b.some(v => v.id === o.id)));

console.log(result);
Eddie
  • 26,593
  • 6
  • 36
  • 58
  • 1
    Just a possible addition, check which array has the greater length before doing the filtering. Otherwise, +1 from me. – Ryan Wilson Jun 01 '18 at 17:15
  • Thanks, I learned something new today by your example, never used .some() before. Also your second example is pretty slick, the ... of ESMAScript6 and the llambdas kind of blew my mind! ;) – Ryan Wilson Jun 01 '18 at 17:32
  • How can i just return True or false not the diff items? – Oliver D May 31 '21 at 21:25
0

Another possibility is to use a Map, allowing you to bring down the time complexity to O(max(n,m)) if dealing with a Map-result is fine for you:

function findArrayDifferences(arr1, arr2) {
const map = new Map();
const maxLength = Math.max(arr1.length, arr2.length);
for (let i = 0; i < maxLength; i++) {
 if (i < arr1.length) {
  const entry = arr1[i];
  if (map.has(entry.id)) {
   map.delete(entry.id);
  } else {
   map.set(entry.id, entry);
  }

 }
 if (i < arr2.length) {
  const entry = arr2[i];
  if (map.has(entry.id)) {
   map.delete(entry.id);
  } else {
   map.set(entry.id, entry);
  }

 }
}
return map;
}

const arr1 = [{id:0,name:'john'},{id:1,name:'mary'},{id:2,name:'pablo'},{id:3,name:'escobar'}];
const arr2 = [{id:0,name:'john'},{id:1,name:'mary'},{id:99,name:'someone else'}];
const resultAsArray = [...findArrayDifferences(arr1,arr2).values()];
console.log(resultAsArray);
eol
  • 23,236
  • 5
  • 46
  • 64