1

I did the following. Very confused whether they are not equal.

var arr1 = []
arr1.push(1)
arr1.push(2)
arr1.push(3)

var arr2 = [1, 2, 3]

var isSame = (arr1==arr2)

Why is isSame false? Very confused about this...

Jasper
  • 11,590
  • 6
  • 38
  • 55
  • You can't compare arrays or objects like this in JavaScript. To check to see if they are identical you'll have to iterate over them. – Andy Jul 13 '15 at 01:01
  • JavaScript (like many other languages), is going to compare pointers when you compare arrays/objects/etc. So the way you can find out if they're equal is to loop through them comparing their values. – Dave Chen Jul 13 '15 at 01:01
  • Check this http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript – Mindastic Jul 13 '15 at 01:02
  • Actually the more complete scenario is I want an array of objects in highchart. The array is created during web execution. The pushed way of get array does not work in highchart? Is this expected? Or I'm doing something silly? – user2528576 Jul 13 '15 at 01:12
  • @user2528576 Highchart doesn't care how your array is created, whether it's with `push` or not, so your problem is somewhere else. You should create a new question with the actual code you're using with Highchart and a description of the actual problem you're having. – Jordan Running Jul 13 '15 at 01:52
  • Writing your own functionality for comparing arrays and take into account all the possible scenarios is possible, but it can become something complex to write. May be you can think about using some third party library like underscore.js which contains many useful methods for doing usual stuff and, also, contains a method `_.isEqual(object1, object2)` that will compare any kind of objects. Also, this library is really light (5.7kb) so it won't introduce any speed issue when loading your scripts. – Mindastic Jul 13 '15 at 01:59

2 Answers2

1

As a rule of thumb, avoid using == since it is subject to complex coercion rules. === is simpler, more efficient and less bug-prone in general. The === operator in JavaScript, for arrays and objects, compares by reference - it only returns true if two variables reference the same object.

var a = [1,2,3];
var b = [1,2,3];
var c = a;
console.log(a === b); // false
console.log(a === a); // true
console.log(a === c); // true

For numbers, bools and strings, the === operator compares by value.

var a = "hi";
var b = "hey";
var c = "hi";
console.log(a === b); // false
console.log(a === c); // true

If you want to compare two numeric arrays by value, the best way of doing it is creating a function particularly for that:

function arrayEquals(a,b){
    for (var i=0, l=a.length; i<l; ++i)
        if (a[i] !== b[i])
            return false;
    return true;
}

This will only work if your array only contains native values - strings, numbers and booleans. If you want to compare a deeper structure, a quick and dirty way is serializing it to JSON and comparing:

var a = [[1,2],3,4];
var b = [[1,2],3,4];
var c = [[1,5],3,4];
console.log(JSON.stringify(a) === JSON.stringify(b)); // true
console.log(JSON.stringify(a) === JSON.stringify(c)); // false

This will work for any structure that is a valid JSON and is actually acceptably fast for usual operations, as JSON.stringify is usually implemented natively. So, tl;dr: just use JSON.stringify on your arrays before comparing.

MaiaVictor
  • 51,090
  • 44
  • 144
  • 286
  • 2
    You had me until "just use JSON.stringify." A function like your `arrayEquals` is great because it returns as soon as it finds two elements that aren't equal. If you have two arrays with hundreds or thousands of elements but the second elements are different, it will stop after doing only two comparisons. `JSON.stringify`, on the other hand, is a nontrivial operation, and you have to apply it to both objects in their entirety before comparing the resulting strings. It's a nice solution for its brevity, but that's where its benefits end. – Jordan Running Jul 13 '15 at 01:48
  • Surprisingly, I've benchmarked JSON.stringify extensively and it seems to be faster than the hand-optimized recursive version for deep structures. That was a while ago, though, so I'm not sure that is still the case. – MaiaVictor Jul 13 '15 at 08:20
  • you had me untill `avoid using ==` – GottZ Jul 13 '15 at 08:59
  • @Viclib Please put your benchmarks up on JSPerf. I'd love to see them. – Jordan Running Jul 13 '15 at 16:35
  • @Jordan You forgot JSPerf is off? – MaiaVictor Jul 13 '15 at 16:47
  • @GottZ please explain. – MaiaVictor Jul 13 '15 at 16:47
  • @Viclib Ah. It was up again the other day; I didn't realize it'd gone down again. ¯\\_(ツ)_/¯ – Jordan Running Jul 13 '15 at 16:49
  • Sadly :( was a great site. – MaiaVictor Jul 13 '15 at 16:49
  • 1
    @Viclib because.. the behaviors of == makes total sense to me. besides that, it does not have anything to do with the main issue in this question. oh and just an addition: JSON.stringify will not convert references. (wich is good in general but bad for comparison) – GottZ Jul 16 '15 at 08:29
  • Uhm I see... what works to you, but it is complete nonsense type-theoretically so I'm going to stick with that. Also, `JSON.stringify` comparison is the equivalent of structural equality - so, the same kind of equality you will find in Haskell, for example. That says something. – MaiaVictor Jul 16 '15 at 20:30
1

when comparing variables you will only compare the variables itself and not their content.

strings, numbers aswell as booleans are simple types. they are always representing their value.

objects are different. if you compare objects, you will just check if an objects reference is equal to the objects reference of the second comparator.

by comparing objects you will never ever compare the variables they contain. objects are simply containers for even more variables. variables can be simple types aswell as objects.

you are simply comparing two foundations to figure out if they are exactly the same.

if you really want to compare the content of an array to the content of another array you need to recursively check every variable it contains aswell.

an example..

var obj = {};

obj.foo = "bar";

(function (o) {
    o.foo = "baz";
})(obj);

console.log(o.foo); // will print "baz"

when doing it with arrays you will get the same result.

you might want to check out this question: Deep comparison of objects/arrays aswell as all of the duplicates

Community
  • 1
  • 1
GottZ
  • 4,824
  • 1
  • 36
  • 46