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

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. Commented Jun 1, 2018 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) Commented Jun 1, 2018 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. Commented Jun 1, 2018 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. Commented Jun 1, 2018 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. Commented Jun 1, 2018 at 17:45

3 Answers 3

42

.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);

Sign up to request clarification or add additional context in comments.

3 Comments

Just a possible addition, check which array has the greater length before doing the filtering. Otherwise, +1 from me.
how can i just return true or false not the items?
@OliverD maybe res.length > 0 ?
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);

3 Comments

Just a possible addition, check which array has the greater length before doing the filtering. Otherwise, +1 from me.
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! ;)
How can i just return True or false not the diff items?
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);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.