区域设置与 ASCII 样式的词典排序进行比较



我正在尝试我希望是一个简单的编码练习:用ASCII风格的词典顺序对Javascript字符串进行排序(例如,在大写字母之前的数字,然后是小写字母......)。

下面是一个片段:

var str1 = "ab";
var str2 = "Ab";
var n = str1.localeCompare(
str2, "en", {sensitivity: 'variant', caseFirst: "upper"}
);

在这种情况下,我希望n1,但它返回-1

从此页面上的文档:

  • 设置为variantsensitivity值将允许区分所有基字母和重音字母,包括大小写
  • 设置为uppercaseFirst值将强制大写字母比较小写字母
  • 缺少usage参数化将默认为sort,无论如何,这在这里无关紧要,因为我指定了variant
  • 缺少ignorePunctuation参数化将默认为false

我假设这些选项会覆盖默认的语言环境设置,尽管我找不到有关此事的任何具体信息。 事实上,如果它默认为en-US并且优先于选项,那么我想情况将被忽略(例如,在此处查看接受的答案)。

我做错了什么?

笔记

  • 我在这里提到"ASCII"的唯一目的是识别一种排序顺序,该排序顺序不会忽略大小写,并在适用的情况下将大写字母排序在小写字母之前。我最终也会将其用于 unicode 字符串。
  • 正如一些人所建议的那样,这可能取决于引擎。 使用 Firefox ESR 52.6.0 和 Chromium 64.0.3282.167 复制。

我不确定你是如何-1.当我运行您提供的确切代码时,我得到1.我只有在用str1.localeCompare(str2)进行测试时才会得到-1.也许记下这个警告:

不需要实现来支持此属性。

如果sensitivity设置为variantcaseFirst设置为upper,这已经是字符串的默认比较。区域设置通常用于将字符变体同义化。此外,在 ASCII 和 Unicode 中,大写已经排在小写之前。所以你只需要-(str1 < str2) || +(str1 > str2)并完全避免函数调用:

var str1 = "ab";
var str2 = "Ab";
var a = str1.localeCompare(
str2, "en", {sensitivity: 'variant', caseFirst: "upper"}
);
var b = -(str1 < str2) || +(str1 > str2);
console.log(a, b);

您可以通过查看字母的大小写来使用解决方法,并使用反映大小写和小字母位置的帮助程序字符串。

排序前的帮助程序数组

index  value
-----  -----
0    a b 
1    a  B
2     Ab 
3     A B

排序后

index  value
-----  -----
3    A B
2    Ab 
1   a  B
0   a b 

var array = ['ab', 'aB', 'Ab', 'AB'],
mapped = array
.map((el, i) => ({ index: i, value: [...el].map(c => c === c.toUpperCase() ? ' ' + c : c + ' ').join('') }))
.sort((a, b) => a.value.localeCompare(b.value)),
result = mapped.map(el => array[el.index]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

最新更新