我想使用localeCompare来测试通过Postgres排序的字符串。
正在使用的排序规则是en_US.utf8
当我使用localeCompare测试降序和升序排序时,它会给我不正确的结果。我可以将哪些语言环境传递给localeCompare来正确处理它?</ p>
例如:
Descending: "negative outcome".localeCompare("a sollicitudin orci") = 1
Ascending: "amet lorem semper auctor.".localeCompare("a sollicitudin orci") = 1
答案 0 :(得分:0)
不幸的是,没有参数可以传递给localeCompare,使其与Postgres的en_US.UTF-8排序相匹配。
Postgres正在遵循Unicode归类算法的实现,该算法在此处记录:http://www.unicode.org/reports/tr10/
相比之下,localeCompare使用Intl.Collator对象中的“CompareStrings”操作。根据规范,“两个字符串以实现定义的方式进行比较。” (https://www.ecma-international.org/ecma-402/1.0/#CompareStrings)。该规范表明实现使用Unicode排序算法,但它只是一个建议,虽然我不确定不同浏览器正在做什么,但我已经在Mac上的Chrome上做了足够的经验测试,以确定无论如何正在做,这与Postgres的实施非常不同。
我目前还不知道任何将Unicode排序算法移植到javascript的库。
因此。如果你绝对需要一个与Postgres排序完全匹配的浏览器端算法,这就是生死,那么我认为你唯一的选择是实际查看规范(http://www.unicode.org/reports/tr10/),可能还有Postgres的源代码,并将其移植到javascript。
规范是非常密集和复杂的,所以实用的方法可能是开发一个足够好的算法,大多数时候匹配Postgres,让你的应用程序优雅地处理角落案例。我找到的最有用的资源就是这个答案https://stackoverflow.com/a/3266430/534086,它使用Latin1校对表提供了一个简单的算法实现,它可能适合使用UTF8。
就我的目的而言,我还没有走过那条路。我编写了一个更粗略的算法:a)首先从两个字符串中删除特殊字符(如空格和符号),并使用localeCompare与'en-US'进行比较,b)断开关系,使用localeCompare比较原始字符串。这是非常粗糙(我有一些测试用例,我知道它不起作用),但在实践中它似乎产生与Postgres相同的结果至少90%的我的实际使用率