Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why or how does this prove JavaScript array equality?

In this answer there is a simple function that will return array equality for arrays that contain primitive values.

However, I'm not sure why it works. Here is the function:

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }

I'm mostly interested in the second half; this bit:

!(a<b || b<a)

Why does the < and > work when comparing the arrays but the == doesn't?

How do the less than and greater than methods work within JavaScript?

like image 942
Bill Rawlinson Avatar asked Feb 17 '12 19:02

Bill Rawlinson


People also ask

Can you check if arrays are equal JavaScript?

To conclude, to compare arrays to check for equality, Lodash's isEqual() function is the way to go if you need all the bells and whistles of checking that objects have the same class. The JSON. stringify() approach works well for POJOs, just make sure you take into account null.

How do you know if an array is equal?

The Arrays. equals() method checks the equality of the two arrays in terms of size, data, and order of elements. This method will accept the two arrays which need to be compared, and it returns the boolean result true if both the arrays are equal and false if the arrays are not equal.

How do you check if all elements in an array are equal JavaScript?

Javascript Useful Snippets — allEqual() In order to check whether every value of your records/array is equal to each other or not, you can use this function. allEqual() function returns true if the all records of a collection are equal and false otherwise.

Why are arrays not equal in JavaScript?

because everything in javascript is an object and arrays are also objects therefore instead of comparing the values or number of elements , it checks the reference of those array which is different that's why it returned false in both the cases.


3 Answers

With </>, the arrays are converted to strings first, and as such do not provide a reliable method of checking equality.

== does not work because objects are checked by reference:

[] == []; // false, two separate objects

var a = [];
a == a; // true, refer to the same object

The </> trick is flawed:

var a = [1, [2, 3]],
    b = [[1, 2], 3];

!(a<b || b<a); // true

This evaluates to true, because they are both converted to the string "1,2,3" before they are checked (</> do not "directly" work for objects).

So basically, you are comparing equality of the strings. For strings, a == b is indeed the same as !(a<b || b<a) - </> for strings check character codes, so two equal strings are neither "smaller" nor "greater" because that's not the case for any character code in the strings.

like image 186
pimvdb Avatar answered Nov 15 '22 19:11

pimvdb


However, I'm not sure why it works.

It doesn't work. Consider

arrays_equal(["1,2"], [1,2])

produces true even though by any definition of array equality based on element-wise comparison, they are different.

arrays_equal([[]], [])

and

arrays_equal([""], [])

are also spurious positives.

Simply adding length checking won't help as demonstrated by

arrays_equal(["1,2",3], [1,"2,3"])

arrays_equal(
    ["",","],
    [",",""])

EDIT:

If you want a succinct way to test structural similarity, I suggest:

function structurallyEquivalent(a, b) {
  return JSON.stringify(a) === JSON.stringify(b);
}

It doesn't stop early on inputs that are obviously different -- it walks both object graphs regardless of how disimilar they are, but so does the function in the OP.

One caveat: when you're using non-native JSON.stringify, it may do strange things for cyclic inputs like:

var input = [];
input[0] = input;
like image 43
Mike Samuel Avatar answered Nov 15 '22 21:11

Mike Samuel


You can compare any two objects using ==. But since > and < are not defined for objects, they are converted to strings. Therefore, [1,2,3]>[2,1,3] is actually doing "1,2,3">"2,1,3"

like image 28
Diego Avatar answered Nov 15 '22 19:11

Diego