如何按照 codePoint 对 JavaScript 字符串进行排序?

4

我希望能够按照包含Unicode字符的字符串字段对对象进行排序。但是,我想按照代码点而不是按照区域设置来排序字符串。因此,这里有一个示例,JavaScript将对象排序,以使 \u24B7b 被视为相同的字符。

排序顺序不正确:

> [{name: 'a'}, {name: 'b'}, {name: 'd'}, {name: '\u24B7'}].sort((a,b)=> a.name.localeCompare(b.name))
[ { name: 'a' }, { name: 'b' }, { name: 'Ⓑ' }, { name: 'd' } ]

然而,这不是我想要的。我希望有以下排序顺序,其中它们被视为不同的字符。当比较字符串并且不包括比较函数时,这是默认行为。

正确的排序顺序(请注意,b\u24B7不再被视为相同的排序字符):

> ['a','b','\u24B7','d'].sort()
[ 'a', 'b', 'd', 'Ⓑ' ]

在实际应用中,字符串将会包含多个字符并且可能含有多个Unicode字符,我们希望按照Unicode编号(即代码点)对它们进行排序。
我的问题是:有没有一种简单的方法可以按照代码点对字符串进行排序?我不想重新实现一个自定义比较器。

你坚持比较代码点,还是比较UTF16代码单元就足够了? - Bergi
不需要是代码点,重要的是Unicode字符需要与其特定于语言环境的同义词区分开来(我不知道这里的正确术语)。 - Andrew Eisenberg
是的,那么标准的字符串比较适合您。 - Bergi
1个回答

3

我通常是这样做的:

let cmp = (a, b) => a > b ? 1 : a < b ? -1 : 0;

objects.sort((a, b) => cmp(a.name, b.name));

或者说
let sortBy = (a, f) => a.sort((x, y) => cmp(f(x), f(y)));

sortBy(objects, x => x.name);

2
你通常使用嵌套的三元操作符吗?真丢人。 - Sterling Archer
3
抛开解释不足,这并不是代码高尔夫。在编写代码时,可读性非常重要,三元运算符尤其是嵌套的情况很难阅读。(顺便说一下,这不是我点的踩) - Sterling Archer
1
嵌套的三元运算符会让人感到烦躁。小心使用。 - rlemon
1
我认为嵌套三元运算符是可以的,只要你使用适当的括号来清晰地标示分组(如果我在代码审查中,我会要求这样做)。但作为答案,我觉得这样也是可以的。我现在正在尝试它。 - Andrew Eisenberg
1
@SterlingArcher,我认为这没有任何问题。三元运算符比“if”语句更有用,而且更容易阅读,至少在功能思维方面是如此。那个单行的“cmp”函数可以通过快速浏览来确定,以比较两个参数值并根据排序比较函数适当地返回1/0/-1。 - Bergi
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接