0

If I have two arrays of objects, like this:

var a1 = [{"a":"b"}, {"b":"c"}, {"d":"e"}], 
    a2 = [{"g":"h"}, {"a":"b"}, {"i":"j"}]

(note that objects may be of any structure, not so simple)

what is the most efficient way to extract all the objects that are in both arrays?

I checked this question: Finding matches between multiple JavaScript Arrays, but this is not the same...

Community
  • 1
  • 1
lyrically wicked
  • 1,185
  • 12
  • 26

3 Answers3

1

extract all the objects that are in both arrays?

Basically you just need to combine Simplest code for array intersection in javascript with Object comparison in JavaScript (instead of using the identity == operator):

var intersection = a1.filter(function(a) {
    return a2.some(function(b) {
        return Object.equals(a, b);
    });
});

Use any Object.equals function that fits your requirements best.

what is the most efficient way?

It depends on your objects. If you can define a reasonable compare function on them so that you can sort the arrays, or if you even can come up with a consistent hashing function, there are faster ways than the above. Check the answers in the linked question.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

To find only first repetitive object and break the procedure you may use a combination .find methods:

const a1 = [{"a":"b"}, {"b":"c"}, {"d":"e"}], a2 = [{"g":"h"}, {"a":"b"}, {"i":"j"}]

const compareObjects = (o1, o2) => JSON.stringify(o1) === JSON.stringify(o2);
const findFirst = (a1, a2) => a1.find(i1 => a2.find(i2 => compareObjects(i1, i2)));

console.log(findFirst(a2, a1)); // {a: "b"}
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
dhilt
  • 18,707
  • 8
  • 70
  • 85
  • This try came from [How to compare two arrays for identical objects](https://stackoverflow.com/questions/46770250/how-to-compare-two-arrays-for-identical-objects)? question which is closed for answers. – dhilt Oct 16 '17 at 13:08
0

You can flatten the objects using JSON.stringify() and then check for intersection.

var a1 = [{"a":"b"}, {"b":"c"}, {"d":"e"}], 
    a2 = [{"g":"h"}, {"a":"b"}, {"i":"j"}]

// flatten objects in second array
var stringifiedA2 = a2.map(function(x) {
    return JSON.stringify(x);
});

// get intersecting objects
var intersecting = a1.filter(function(x) {
    return stringifiedA2.indexOf(JSON.stringify(x)) !== -1;
});

intersecting will contain the object {"a": "b"}

techfoobar
  • 65,616
  • 14
  • 114
  • 135
  • @techfoobar: and what can you say about performance? What's the maximum arrays length that you recommend to be handled by this code? – lyrically wicked Feb 13 '14 at 07:01
  • Large objects will likely take more time to be stringified and compared. If your arrays or the objects within are too large, then perhaps this is not the way to go since there is a lot of stringifying, string object creation and comparing taking place in the above code. – techfoobar Feb 13 '14 at 08:41
  • 1
    Notice that `JSON.stringify` is not bound to preserve any property order, so `JSON.stringify({a:1,b:2}) == JSON.stringify({b:2,a:1})` could work or maybe not. – Bergi Feb 13 '14 at 09:40
  • 1
    @Bergi - Yes, this is not a reliable solution if the objects have more than one property. – techfoobar Feb 13 '14 at 11:49