10

Have a look at this code sample or go to the jsfiddle

function printRelation(a, b, out) {
 var text;
 if (a === b) {
 text = "a === b";
 } else if (a == b) {
 text = "a == b";
 } else {
 text = "a != b";
 }
 $('#' + out).text(text);
}
var a = [0, 0, 2], b = a;
printRelation(a, b, 'out1');
a = [0, 0, 2];
b = [0, 0, 2];
printRelation(a, b, 'out2');

I would have expected both tests to output a === b, but only the first one does. The second one outputs a != b. Can anyone explain this behaviour? How can I efficiently compare arrays in javascript?

asked Oct 7, 2012 at 15:59
2
  • Possible duplicate of stackoverflow.com/questions/3115982/… Commented Oct 7, 2012 at 16:01
  • I guess the === operator compares arrays by reference, which would explain the observed behaviour. EDIT: Answered by Pointy in the meantime. Commented Oct 7, 2012 at 16:01

4 Answers 4

26

You can use the Underscore.js library's isEqual method.

http://underscorejs.org/#isEqual

Performs an optimized deep comparison between the two objects, to determine if they should be considered equal.

var moe = {name : 'moe', luckyNumbers : [13, 27, 34]};
var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
moe == clone;
=> false
_.isEqual(moe, clone);
=> true

UPDATE

Lodash is inspired by underscore, but nowadays is superior solution

https://lodash.com/docs/#isEqual

Performs an optimized deep comparison between the two objects, to determine if they should be considered equal.

var object = { 'a': 1 };
var other = { 'a': 1 };
_.isEqual(object, other);
// => true
object === other;
// => false
answered Oct 7, 2012 at 16:05
Sign up to request clarification or add additional context in comments.

1 Comment

note that order matters in an array, so _.isEqual([1, 2, 3], [3, 2, 1]) => false
12

Use lodash.

_.isEqual([1,2],[1,2])

Also works with objects.

_.isEqual({a:1}, {a:1})
answered Oct 7, 2012 at 16:10

1 Comment

Just wanted to say : this is working great for checking [1, 2] with [1, 2], but not for checking [1, 2] with [2, 1] (lodash check if order is the same).
7

Arrays are Objects in javascript. And comparing objects can’t be done using == like you would normally use when comparing strings or numbers.

There are many other ways to compare arrays, my favourite is using JSON:

if ( JSON.stringify(a) == JSON.stringify(b) ) {
 // equal

Note that assigning a pre-existing object to a variable like you do when you write b = a is just copying a reference. They both point to the same array.

You would have to do b = a.slice() to get a real copy.

answered Oct 7, 2012 at 16:00

6 Comments

Nice idea. Works for usual cases but not general purpose.
Nice solution! +1... It also works with objects, but be careful: var a = {a:0, b:0, c:2}; var b = {c:2, b:0, a:0}; would result "false".
@Thomas true, they need to have the same "order" to equal so it’s mostly for arrays I guess.
JSON.stringify'ing the arrays has other limitations as well since JSON supports only a subset of the value types supported in JavaScript. I personally think it's overkill to create JSON strings, especially considering its serious limitations.
@Thomas not necessarily; strictly speaking the behavior is really not well-defined for objects, as JavaScript does not specify the order of property iteration in for ... in loops. Of course it can generally be relied upon, but it's a little worrisome to do so from a formal standpoint.
|
2

JavaScript array comparisons like you've written are just simple object reference comparisons. They're not "deep" comparisons element by element.

You can write your own comparison function, something to check that the lengths are the same and the the elements are the same, either in order or not, as fits your needs. edit As others point out, there are several libraries that include array comparison functions. If you find one that meets your definition of "equality" (not unlikely), and you don't mind considering incorporating that library into your architecture, that might be a good idea.

answered Oct 7, 2012 at 16:00

10 Comments

And don't forget to do the reference check first too, in the custom function.
@MarioDeSchaepmeester ah yes that's a good idea! No use doing extra work if the two arrays are really the same array!
"Write your own." Christ. No.
@StefanKendall: Why would we be afraid of writing a little reusable code that suits our specific needs?
@StefanKendall that reflects a limited view of reality there. For all we know, the OP may consider two arrays to be "equal" if they contain the same elements, but not necessarily in the same order. Perhaps they're equal if a string "17" in one array can match a numeric 17 in the other. The point is that the meaning of "equal" is not necessarily always the same. If a library is already in use that contains some generic array equality test, then of course it would be foolish not to use it.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.