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

6
  • 2
    it's super-easy since none of those objects are in both arrays... Commented Feb 13, 2014 at 5:58
  • Can you explain, I don't understand... for example, {"a":"b"} is in two arrays... Commented Feb 13, 2014 at 6:04
  • 1
    These are different objects which happen to have the same property name and value. a1[0] === a2[1] is false. So, it looks like you are considering two objects as equal if they have the same properties and values, is that correct? Commented Feb 13, 2014 at 6:04
  • in js, all object literals are distinct entities. even if they have the same properties and values, they are different objects and o1!=o2... Commented Feb 13, 2014 at 6:05
  • Of course, I meant "the same properties and values", not the same objects Commented Feb 13, 2014 at 6:07

3 Answers 3

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.

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

Comments

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"}

1 Comment

This try came from How to compare two arrays for identical objects? question which is closed for answers.
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"}

4 Comments

@techfoobar: and what can you say about performance? What's the maximum arrays length that you recommend to be handled by this code?
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.
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 - Yes, this is not a reliable solution if the objects have more than one property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.