我能看到这个用例,我对它感到困惑:
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",忽略了这个符号。
发布于 2022-10-03 18:28:51
默认字符串排序算法使用要比较的字符串中每个代码单元的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"]
https://stackoverflow.com/questions/73939121
复制相似问题