gpt4 book ai didi

javascript - 为什么 JavaScript `Intl.Collator.prototype.compare()` 方法会产生与特殊字符的传统 UTF-16 比较不同的结果?

转载 作者:行者123 更新时间:2023-12-05 03:37:12 24 4
gpt4 key购买 nike

今天,我偶然发现了 JavaScript/ECMAScript 国际化 API 的一个奇怪问题,我无法在任何地方找到合适的解释。比较两个特定字符时我得到不同的结果 - 正斜杠 (/) 和下划线 (_) 字符使用:

  1. 普通/传统基于 UTF-16 的比较
  2. Intl.Collat​​or.prototype.compare() 方法

基于普通/传统 UTF-16 的比较

// Vanilla JavaScript comparator
const cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;

console.log(cmp('/', '_'));
// Output: -1

// When sorting
const result = ['/', '_'].sort(cmp);

console.log(result);
// Output: ['/', '_']

Intl.Collat​​or.prototype.compare() 方法

const collator = new Intl.Collator('en', {
sensitivity: 'base',
numeric: true
});

console.log(collator.compare('/', '_'));
// Output: 1

// When sorting
const result = ['/', '_'].sort(collator.compare);

console.log(result);
// Output: ['_', '/']

问题

为什么这两种技术会产生不同的结果?这是 ECMAScript 实现中的错误吗?我在这里遗漏/未能理解什么?是否有其他此类字符组合会针对英语 (en) 语言/区域设置产生不同的结果?

编辑 2021-10-01

正如@t-j-crowder 指出的那样,将所有“ASCII”替换为“UTF-16”。

最佳答案

一般情况

当您使用 < 时和 >在字符串上,它们根据 UTF-16 代码单元值进行比较(不是 ASCII,但 ASCII 与许多常见字符的这些值重叠)。委婉地说,这是有问题的。例如,问法国人是否 "z" < "é"应该真的是真的(表明 zé 之前):

console.log("z" < "é"); // true?!?!

当您使用 Intl.Collator.prototype.compare 时,它根据您提供的选项为您的语言环境使用适当的排序规则(松散地排序)。在许多情况下,这可能与 UTF-16 代码单元值的结果不同。例如,即使在 en 中语言环境,Collator返回 z 更合理的结果之后 é :

console.log(new Intl.Collator("en").compare("z", "é")); // 1

_/特别是

我不能具体告诉你为什么_/en 中的 UTF-16 代码单元有不同的顺序您正在使用的语言环境(以及我正在使用的语言环境),无论它是 en-US , en-UK , 或者是其他东西。但是发现它们在 ASCII 和 Unicode 之间的顺序不同也就不足为奇了。 (请记住,_/ 的 UTF-16 代码单元值来自它们的 ASCII 值。)

ASCII 的顺序是在 1960 年代早期精心设计的(a PDF 对此进行了精彩的详细介绍),但除了A-Z 和 0-9 的排序。 /是 1963 年的原始 ASCII。_直到 1967 年才被添加到可用位置之一,该位置的数值高于 / .可能没有比 _ 更重要的原因了。晚于/高于(数字)/在 ASCII 中。

Unicode 的整理顺序是在 1990 年代(一直到今天)根据不同的目标(包括语言目标)、设计要求和设计约束精心设计的。据我所知(我不是 Unicode 专家),Unicode 的整理由 TR10 描述。和 TR35 的第 5 部分.我还没有找到为什么 _ 的具体理由在 / 之前在根排序规则中(en 使用根排序规则)。我确定它在某处。我确实注意到它的一个方面似乎是按类别分组。 _ 的类别是“连接标点符号”,而 / 的类别是“其他标点符号”。也许这与为什么 / 有关晚于 _ .

但根本的答案是:它们之所以不同,是因为 ASCII 的排序和 Unicode 整理是根据不同的约束和要求设计的。

关于javascript - 为什么 JavaScript `Intl.Collator.prototype.compare()` 方法会产生与特殊字符的传统 UTF-16 比较不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69405786/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com