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

发布于 2025-01-06 12:20:05 字数 429 浏览 0 评论 0 原文

这个答案中有一个简单的函数,它将返回包含原始值的数组的数组相等性。

但是,我不确定它为什么有效。这是功能:

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

我最感兴趣的是后半部分;这一点:

!(a<b || b<a)

为什么在比较数组时 <> 可以工作,而 == 却不行?

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

别挽留 2025-01-13 12:20:05

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

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

[] == []; // 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 - </> 对于字符串检查字符代码,因此两个相等的字符串既不会“更小”也不会“更大”,因为字符串中的任何字符代码都不是这种情况。

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.

余厌 2025-01-13 12:20:05

但是,我不确定它为什么有效。

这不起作用。 考虑也会

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

即使根据基于元素比较的数组相等的任何定义,

arrays_equal([[]], [])

产生 true,它们是不同的。并且

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;

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;
千鲤 2025-01-13 12:20:05

您可以使用 == 比较任意两个对象。但自从>且<不是为对象定义的,它们被转换为字符串。因此,[1,2,3]>[2,1,3]实际上是在做"1,2,3">"2,1,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"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文