【问题标题】:localeCompare when testing strings sorted in en-us utf8测试以 en-us utf8 排序的字符串时的 localeCompare
【发布时间】:2017-10-18 17:43:36
【问题描述】:

我想使用 localeCompare 来测试通过 Postgres 排序的字符串。

正在使用的排序规则是 en_US.utf8

当我使用 localeCompare 测试降序和升序排序时,它给了我不正确的结果。我可以将什么语言环境传递给 localeCompare 以正确处理此问题?

例如:

Descending: "negative outcome".localeCompare("a sollicitudin orci") = 1

Ascending: "amet lorem semper auctor.".localeCompare("a sollicitudin orci") = 1

【问题讨论】:

  • 您希望使用哪种语言进行比较返回负数?
  • 所以升序应该是 -1,因为第二个字符串中的空格“小于”第一个字符串中的 m。语言是英语
  • 我尝试将 'en-US.utf8' 传递给 localeCompare 但返回错误
  • 您可以通过交换字符串来指定是升序还是降序:"a sollicitudin orci".localeCompare("amet lorem semper auctor.") = -1

标签: javascript node.js locale


【解决方案1】:

很遗憾,您无法将任何参数传递给 localeCompare 以使其匹配 Postgres 的 en_US.UTF-8 排序。

Postgres 遵循 Unicode 排序算法的实现,此处记录了该算法:http://www.unicode.org/reports/tr10/

相比之下,localeCompare 使用来自 Intl.Collat​​or 对象的“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% 的实际使用情况.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 2018-03-18
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多