问题
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?
回答1:
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.
回答2:
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;
回答3:
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"
来源:https://stackoverflow.com/questions/9334189/why-or-how-does-this-prove-javascript-array-equality