javascript 令人惊讶的数组比较

IT技术 javascript arrays comparison
2021-02-01 12:25:04

我正在尝试比较 javascript 中的两个数组。

我想要的是:

a < b ⇔ ∃ i ≥ 0 st a[i] < b[i] 并且∀ 0 ≤ j < i, a[j] = b[j]

因此,非负数数组按需要工作:

firebug> [0,1,2,3,4] < [1,0,0]
true

并按预期将负数与零进行比较:

firebug> [-1, 1] < [0, 0]
true

但是将负数与负数进行比较是......令人惊讶:

firebug> [-2] < [-1]
false
firebug> -2 < -1
true

这里发生了什么,所以我可以纠正我对javascript中数组比较意味着什么的直觉

3个回答

数组被转换为一个字符串,归结为.join(),然后用逗号 ( ,) 作为分隔符连接元素

"-1,1" < "0,0" === true

因为字符码-(45)是比小字符码0(48)。

另一方面,

"-2" < "-1" === false

因为第二字符代码进行比较(第一均-,所以,不给结果还),而对于字符代码2(50)是更大的比的字符代码1(49),所以这产率false

它归结为字典排序(即通过字符代码)而不是数字排序,即使元素是数字(因为字符串强制)。

基本上不推荐比较数组。它被隐式定义为字符串比较,但这会产生令人惊讶的结果。

@jAndy:它会,但它再次仅适用于单元素数组。-2 - 1会清楚一点...
2021-03-21 12:25:04

没有类似于您所描述的任何形式的 JavaScript 数组比较之类的东西。

在所有情况下发生的情况是,您的数组首先通过将它们的内容连接在一起而转换为字符串。因此,字符串“-2”小于字符串“-1”,因为字符“2”在字符集中出现在“1”之后。类似地,“-1,1”小于“0,0”,因为“-”字符出现在数字之前。

您可以亲眼看到在所有情况下的比较:

array1 < array2

得到完全相同的结果:

("" + array1) < ("" + array2)

或者:

array1.join(",") < array2.join(",")

我找不到关于如何在 Javascript 中实际比较数组并获得“预期”结果的答案,所以这里是代码

compareArrays = function(a, b) {
  var elA, elB, i, len; 
  for (i = 0, len = Math.min(a.length, b.length); i < len; i++) {               
    elA = a[i], elB = b[i];
    if (elA > elB) return 1;
    if (elA < elB) return -1;
  }
  return b.length - a.length;
};

console.log(compareArrays([-2], [-1])) # -1
console.log(compareArrays([], [])) # 0
console.log(compareArrays([null], [undefined])) # 0
console.log(compareArrays([1, 2, 3], [1, 2, 3, 4])) # 1
console.log(compareArrays([0, 2], [0, 1])) # 1
console.log(compareArrays([1], [NaN])) # 0
console.log(compareArrays([NaN], [1])) # 0