javascript - 为什么 Intl.Collat​​or 对负数进行降序排序?

标签 javascript intl collator

我遇到了这个用例,但对此感到困惑:

const naturalCollator = new Intl.Collator(undefined, {
  numeric: true,
  sensitivity: 'base'
});
const comparator = (a, b) => naturalCollator.compare(a, b);

const numbers = [-1, 0, 1, 10, NaN, 2, -0.001, NaN, 0, -1, -Infinity, NaN, 5, -10, Infinity, 0];

console.log(numbers.sort(comparator));

结果数组以降序排列负数,而以升序排列正数。例如:

[-3, 1, -2, 2].sort(comparator)
// [-2, -3, 1, 2]

Intl.Collator是“语言敏感的字符串比较”,它是否简单地忽略符号并且只将每个数字评估为正数?

编辑

另一个不一致是这个:

["b1", "a-1", "b-1", "a+1", "a1"].sort(comparator);
// ['a-1', 'a+1', 'a1', 'b-1', 'b1']

在哪里'a' < 'b'所以顺序没问题,但是'-' > '+'那为什么是"a-1"之前 "a+1"

换句话说,无论字符代码如何,负号都被认为小于正号,但是"-1"被认为小于 "-2" , 忽略标志。

最佳答案

默认的字符串排序算法使用被比较字符串中每个代码单元的 unicode 值。这称为“词典排序”。

当您设置整理器选项时,您正在定义对此行为的特定覆盖(您可以将它们视为比字典排序更高优先级的规则)。

这是相关规范部分的链接:https://tc39.es/ecma402/#sec-collator-comparestrings

比较数字值时(如您的示例),第一步是将数字强制转换为字符串,然后再用于内部排序函数。

使用 numeric 时选项,效果仅适用于分类为数字的代码单元。

在字符串化负值的情况下,连字符被评估为非数字字符。然后将连续的数字序列评估为类似数字的组。

在对以连字符和数字开头的其他字符串进行排序时,您可以看到这种效果:

const opts = { numeric: true, sensitivity: 'base' };
const naturalCollator = new Intl.Collator(undefined, opts);

const values = [-3, 1, -2, 2, '-foo', '-bar', 'foo', 'bar'];

console.log(values.sort(naturalCollator.compare));
//=> [-2, -3, "-bar", "-foo", 1, 2, "bar", "foo"]


numeric 选项有用的另一个例子:考虑一系列带有数字子字符串的文件名,用于分组排序:

const opts = { numeric: true, sensitivity: 'base' };
const naturalCollator = new Intl.Collator(undefined, opts);

const fileNames = [
  'IMG_1.jpg',
  'IMG_2.jpg',
  'IMG_3.jpg',
  // ...
  'IMG_100.jpg',
  'IMG_101.jpg',
  'IMG_102.jpg',
  // ...
  'IMG_200.jpg',
  'IMG_201.jpg',
  'IMG_202.jpg',
  // etc...
];

fileNames.sort();
console.log(fileNames); // 🙈
//=> ["IMG_1.jpg", "IMG_100.jpg", "IMG_101.jpg", "IMG_102.jpg", "IMG_2.jpg", "IMG_200.jpg", "IMG_201.jpg", "IMG_202.jpg", "IMG_3.jpg"]

fileNames.sort(naturalCollator.compare);
console.log(fileNames); // 🤩
//=> ["IMG_1.jpg", "IMG_2.jpg", "IMG_3.jpg", "IMG_100.jpg", "IMG_101.jpg", "IMG_102.jpg", "IMG_200.jpg", "IMG_201.jpg", "IMG_202.jpg"]

关于javascript - 为什么 Intl.Collat​​or 对负数进行降序排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73939121/

相关文章:

javascript - 在 Angular 6 和 Rxjs 6 中取消挂起的 HTTP 请求并再次触发 fromEvent

php - 在默认 Mac OS X Leopard 捆绑 PHP 配置上安装/启用 PHP Pecl Intl 扩展

javascript - Intl.DateTimeFormat 不输出 2 位月份+日期的分隔符(IE 11)

java - 如何使用整理器按属性排序? ( java )

javascript - 如何从虚拟专用服务器检索文本文件?

javascript - 在正则表达式方面需要帮助

javascript - 使用 Mocha 和 Chai 在 JavaScript 中测试随机数函数

带有 IntlDateFormatter 的 PHP

Javascript如何按字符串的数值对对象数组进行排序