Javascript localeCompare与ASCII风格的词典排序

Javascript localeCompare与ASCII风格的词典排序,javascript,string,sorting,Javascript,String,Sorting,我尝试的是我希望在编码方面是一个微不足道的练习:按照ASCII风格的字典顺序对Javascript字符串排序(例如,数字在大写字母之前,小写字母之前…) 下面是一个片段: var str1 = "ab"; var str2 = "Ab"; var n = str1.localeCompare( str2, "en", {sensitivity: 'variant', caseFirst: "upper"} ); 在本例中,我希望n是1,但它返回-1 从第页的文档中: 将敏感度值设置为

我尝试的是我希望在编码方面是一个微不足道的练习:按照ASCII风格的字典顺序对Javascript字符串排序(例如,数字在大写字母之前,小写字母之前…)

下面是一个片段:

var str1 = "ab";
var str2 = "Ab";
var n = str1.localeCompare(
    str2, "en", {sensitivity: 'variant', caseFirst: "upper"}
);
在本例中,我希望
n
1
,但它返回
-1

从第页的文档中:

  • 敏感度
    值设置为
    变量
    将允许区分所有基本字母和重音字母,包括大小写
  • 设置为
    upper
    caseFirst
    值将强制大写字母与小写字母进行比较
  • 缺少
    用法
    参数化将默认为
    排序
    ,因为我指定的是
    变量
  • 缺少
    忽略标点符号
    参数化将默认为
    false
我假设这些选项覆盖了默认的语言环境设置,尽管我找不到关于这个问题的任何具体信息。 事实上,如果它默认为
en-US
,并且优先于选项,那么我认为案例将被忽略(例如,请参阅已接受的答案)

我做错了什么

注释

  • 我在这里提到“ASCII”的唯一目的是确定不忽略大小写的排序顺序,并在适用的情况下将大写字母排序在小写字母之前。我最终也会将其用于unicode字符串
  • 正如一些人所建议的,这可能取决于发动机。 与Firefox ESR 52.6.0和Chromium 64.0.3282.167一起复制

您可以通过查看字母大小写来使用变通方法,并使用反映上下字母位置的辅助字符串

排序前的助手数组

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数组=['ab','ab','ab','ab'],
映射=数组
.map((el,i)=>({index:i,value:[…el].map(c=>c===c.toUpperCase()?''+c:c+'').join(''))
.sort((a,b)=>a.value.localeCompare(b.value)),
结果=mapped.map(el=>array[el.index]);
控制台日志(结果)

。作为控制台包装{max height:100%!important;top:0;}
我不确定您是如何得到
-1
。当我运行您提供的确切代码时,我得到
1
。当使用
str1.localeCompare(str2)
进行测试时,我只得到
-1
。请注意:

不需要实现来支持此属性

如果您的
敏感度
设置为
变量
,而
案例优先
设置为
上限
,则这已经是字符串的默认比较。区域设置通常用于同义化字符变体。此外,在ASCII和Unicode中,大写字母已经排在小写字母之前。因此,您只需要
-(str1str2)
,并完全避免函数调用:

var str1=“ab”;
var str2=“Ab”;
var a=str1.localeCompare(
str2,“en”{敏感度:'variant',caseFirst:'upper}
);
变量b=-(str1str2);

控制台日志(a,b)运行您的代码,我实际上得到
1
。您得到的结果取决于浏览器。它适用于chrome,但不适用于edge。@NinaScholz谢谢,这是有道理的。在notes中添加了浏览器。现在在notes中添加了浏览器…注意:JavaScript中的所有字符串都是Unicode(UTF-16编码)。此外,尽管JavaScript支持区域设置,但它本身并不支持识别所有数字和字母字符,包括Unicode类别。所以,你必须使用大量的代码点范围。谷歌的代码生成器,帮助在这种情况下。谢谢你的回答。尼娜认为这与浏览器有关。将尝试使用不同的引擎-我希望我的代码得到所有人的支持,但这并不意味着功能最终可能会有所不同,我想。。。叹气。当我从代码段直接运行您的代码时,更新的浏览器和
var a
对我来说仍然是
-1
。然而,奇怪的是,您的变通解决方案确实返回了
1
-进一步研究…@Mena“变通解决方案”,我建议它是一个实际的解决方案,而不是特定于浏览器的黑客攻击,它依赖于规范。它返回
1
,这并不奇怪,它的比较是基于字符unicode值的。我选词不好。我正在考虑使用它,因为它看起来是目前为止唯一可靠的解决方案。我突然想到,您想要使用
localeCompare()
实际上是有原因的:在适当的支持下,您将使用以下顺序:
AaBbCcDdEe…
而ASCII/Unicode顺序是
ABCDE。。。abcde…
例如,您可能不想要
Z
a
谢谢尼娜。这似乎比Patrick的解决方案更麻烦,所以最终我会选择他的简单方案。