【问题标题】:Array sorting is broken with Bigint In JS?JS中的Bigint破坏了数组排序?
【发布时间】:2020-12-24 16:16:39
【问题描述】:

似乎Array.prototype.sort()BigInt 破坏了

这行得通

const big = [1n, 2n, 3n, 4n];
big.sort();
console.log(big);
// expected output: Array [1n, 2n, 3n, 4n]

但这不是:(

const big = [1n, 2n, 3n, 4n];
big.sort((a,b)=>a-b);
console.log(big);
//Error: Cannot convert a BigInt value to a number

还是我做错了什么?

【问题讨论】:

  • 这能回答你的问题吗? How to sort an array of integers correctly
  • 我认为你误读了这个问题,似乎比较函数只期望整数值作为回报..
  • 我相信BigInt 的处理方式与典型数值不同。您可能需要使用一个单独的库,以便更轻松地处理这些类型的值,以便正确地减去这两者。我以前没有使用过BigInt,但根据我有限的理解,这可能是问题的根源。
  • 您可以使用Number(a-b),但不确定这是否是正确的处理方式。它将 BigInt 转换为数字。如果差值大于Number.MAX_SAFE_INTEGER (2^53 - 1),则不起作用
  • 在 Mozilla 的网站developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…(在第三个代码块中)找到了这个。它表明不支持按您拥有的方式进行排序,并提供了一种方法来做您正在寻找的事情。

标签: javascript


【解决方案1】:

JavaScript 排序方法需要一个函数作为参数,该函数可以比较数组的两个元素并返回正数、负数或零。数字是这里的关键词。

BigInt 加法和减法等运算返回 BigInt 类型,而不是 Number 类型。这就是您遇到错误的原因。

所以,这样的事情应该可以完成这项工作

const big = [1n, 2n, 3n, 4n];
big.sort((a ,b) => {
  if(a > b) {
    return 1;
  } else if (a < b){
    return -1;
  } else {
    return 0;
  }
});
console.log(big);

有趣的是,MDN document that I linked to previously 还建议了如何对 BigInts 数组进行排序,而且很简洁:

将整个部分复制到这里以供后代使用:

const mixed = [4n, 6, -12n, 10, 4, 0, 0n]
// ↪  [4n, 6, -12n, 10, 4, 0, 0n]

mixed.sort() // default sorting behavior
// ↪  [ -12n, 0, 0n, 10, 4n, 4, 6 ]

mixed.sort((a, b) => a - b)
// won't work since subtraction will not work with mixed types
// TypeError: can't convert BigInt to number

// sort with an appropriate numeric comparator
mixed.sort((a, b) => (a < b) ? -1 : ((a > b) ? 1 : 0))
// ↪  [ -12n, 0, 0n, 4n, 4, 6, 10 ]

【讨论】:

【解决方案2】:

原因是 sort 回调函数中的 a - b 将返回 BigInt 数据类型,而 sort 期望它返回(或可以强制转换为)数字数据类型。

所以你可以使用a &gt; b || -(a &lt; b)作为回调表达式:

const big = [10n, 9n, 8n, 7n];
big.sort((a, b) => a > b || -(a < b));
console.log(big + ""); // 7,8,9,10

请注意,第一个版本(没有sort 回调)通常不起作用,因为sort 会将元素作为字符串进行比较。很明显,这会产生未按数字排序的结果:

const big = [10n, 9n, 8n, 7n];
big.sort(); // string-based sort
console.log(big + ""); // 10,7,8,9 is wrong

【讨论】:

    【解决方案3】:

    这可能一开始似乎被破坏了,但事实并非如此,问题是比较函数的定义总是期望返回值 -1, 0, 1 并且没有理由期望 bigint 为 -1 0 1 原因他们都在正常的范围内.. 所以这应该解决

    big.sort((a,b)=>a<b?-1:(a>b?1:0));
    

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      相关资源
      最近更新 更多