It seems like Array.prototype.sort()
is broken with BigInt
This works
const big = [1n, 2n, 3n, 4n];
big.sort();
console.log(big);
// expected output: Array [1n, 2n, 3n, 4n]
But this doesn't :(
const big = [1n, 2n, 3n, 4n];
big.sort((a,b)=>a-b);
console.log(big);
//Error: Cannot convert a BigInt value to a number
or am i doing something wrong?
BigInt is a built-in object in JavaScript that provides a way to represent whole numbers larger than 253-1. The largest number that JavaScript can reliably represent with the Number primitive is 253-1, which is represented by the MAX_SAFE_INTEGER constant.
The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. With BigInts, you can safely store and operate on large integers even beyond the safe integer limit for Numbers. A BigInt is created by appending n to the end of an integer or by calling the constructor.
BigInt is a new data type intended for use when integer values are larger than the range supported by the Number data type. This data type allows us to safely perform arithmetic operations on large integers, represent high-resolution timestamps, use large integer IDs, and more without the need to use a library.
Array.prototype.sort() The sort() method sorts the elements of an array in place and returns the reference to the same array, now sorted. The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.
JavaScript sort method requires a function as a parameter that can compare two elements of the array and return either a positive number, or a negative number or zero. Number is the keyword here.
BigInt operations like addition and subtraction returns BigInt type and not a Number type. And that's why the error you are getting.
So, Something like this should do the job
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);
Interestingly, MDN document that I linked to previously, also suggests how to sort an array of BigInts, and it is concise:
Copying the whole section here for posterity:
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 ]
The reason is that a - b
in the sort
callback function will return a BigInt data type, while sort
expects it to return something that is (or can coerce to) a Number data type.
So you can use a > b || -(a < b)
as callback expression:
const big = [10n, 9n, 8n, 7n];
big.sort((a, b) => a > b || -(a < b));
console.log(big + ""); // 7,8,9,10
Note that the first version (without sort
callback) does not work in general, because then sort
will compare the elements as strings. It is clear that this can yield results that are not numerically sorted:
const big = [10n, 9n, 8n, 7n];
big.sort(); // string-based sort
console.log(big + ""); // 10,7,8,9 is wrong
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With