为什么或如何证明JavaScript数组相等?

时间:2012-02-17 19:30:16

标签: javascript arrays equality

this answer中有一个简单的函数,它将为包含原始值的数组返回数组相等。

但是,我不确定它为什么会起作用。这是功能:

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

我最感兴趣的是下半场;这一点:

!(a<b || b<a)

为什么<>在比较数组时有效但==没有?

小于和大于方法在JavaScript中如何工作?

3 个答案:

答案 0 :(得分:11)

使用< / >,数组首先转换为字符串,因此不提供检查相等性的可靠方法。

==不起作用,因为通过引用检查对象:

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

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

< / >技巧存在缺陷:

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

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

这评估为true,因为它们在被检查之前都被转换为字符串"1,2,3"< / >不“直接”为对象工作)

所以基本上,你要比较字符串的相等性。对于字符串,a == b对于字符串检查字符代码确实与!(a<b || b<a) - < / >相同,因此两个相等的字符串既不“小”也不“大”,因为字符串中的任何字符代码都不是这种情况。

答案 1 :(得分:5)

  

但是,我不确定它为什么会起作用。

它不起作用。考虑

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

生成true,即使基于元素比较的任何数组相等定义,它们也是不同的。

arrays_equal([[]], [])

arrays_equal([""], [])

也是假阳性。

所示,简单地添加length检查无济于事
arrays_equal(["1,2",3], [1,"2,3"])

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

编辑:

如果您想要一种简洁的方法来测试结构相似性,我建议:

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

它不会在显然不同的输入上提前停止 - 它会走两个对象图,无论它们有多么不同,但OP中的功能也是如此。

一个警告:当你使用非本地JSON.stringify时,它可能会为循环输入做些奇怪的事情,如:

var input = [];
input[0] = input;

答案 2 :(得分:4)

您可以使用==比较任意两个对象。但是因为&gt;和&lt;没有为对象定义,它们被转换为字符串。因此,[1,2,3]>[2,1,3]实际上正在执行"1,2,3">"2,1,3"