【问题标题】:Sorting Special Characters in Javascript (Æ)在 Javascript 中对特殊字符进行排序 (Æ)
【发布时间】:2025-12-25 18:35:12
【问题描述】:

我正在尝试根据对象的name 属性对对象数组进行排序。有些名字以“Æ”开头,我希望它们像“Ae”一样被排序。我目前的解决方案如下:

myArray.sort(function(a, b) {
  var aName = a.name.replace(/Æ/gi, 'Ae'),
      bName = b.name.replace(/Æ/gi, 'Ae');
  return aName.localeCompare(bName);
});

我觉得应该有更好的方法来处理这个问题,而不必手动替换每个特殊字符。这可能吗?

如果有什么不同,我会在 Node.js 中执行此操作。

【问题讨论】:

  • 我不这么认为。您还可以创建自己的 abecedary,在您想要的位置包含“Æ”。但是之后会被当作一个字符来处理,所以效果和当作两个字符来处理是不一样的。
  • 为什么要这样排序? 'Æ' 通常出现在 'Z' 之后。
  • @PaulButcher 我正在尝试匹配已经确定“Æ”本质上是“Ae”的东西。我个人也认为将“Æ”放在其他任何地方都是不直观的。
  • RE 前者 - 如果 Æ 在您使用的环境中是 AE,那么为什么不立即将其更改为 AE? RE 后者 - 在大多数使用它的现代语言中,按字母顺序将其放在 Z 之后(或在没有 Z 的语言中将 Y 放在 Y 之后)因此,将它放在 Z (或 Y)之后的直观位置。如果你想把它移到不正常的地方,你必须像处理任何其他字母一样做。
  • @PaulButcher 在这种情况下,使用 Æ,如果 Æ 正确属于 Z 之后,那么我知道我必须像我一样进行替换。暂时忽略 Æ - 'À'.localeCompare('Z'); 返回 102,说 À 在 Z 之后。这肯定似乎不直观。出于排序目的,我希望 À 等于 A。 iOS 有排序功能localizedCaseInsensitiveCompare,它将Æ 放在Ae 附近,À 放在A 附近,这让我觉得我所要求的并不完全荒谬。

标签: javascript node.js sorting special-characters


【解决方案1】:

没有更简单的方法。不幸的是,即使是问题中描述的方式也太简单了,至少在考虑到可移植性的情况下是这样。

localeCompare 方法在定义上是依赖于实现的,它通常取决于底层操作系统的 UI 语言,尽管它也可能在同一台计算机上的浏览器(或其他 JavaScript 实现)之间有所不同。很难找到关于它的任何文档,因此即使您的目标是编写不可移植的代码,您也可能需要进行大量测试以查看应用了哪种排序规则。参照。给Sorting strings is much harder than you thought!

因此,要进行可控且可移植的比较,您需要自己编写代码,除非您有幸找到恰好适合您需求的其他人的代码。从积极的方面来说,case conversion 方法是 JavaScript 中为数不多的本地化就绪的部分之一:它们应用 Unicode 大小写映射规则,例如'æ'.toUpperCase() 在任何实现中都会产生 Æ。

一般来说,对字符串进行排序需要一个复杂的函数,该函数应用为一种语言或其他一些规则定义的特定排序规则,例如泛欧排序规则(用于多语言内容)。但是,如果我们可以将自己限制为只处理除 Ascii 之外的少数字母的排序规则,我们可以使用如下代码对德语进行简化排序(摘自 by book Going Global with JavaScript and Globalize.js):

String.prototype.removeUmlauts = function () {
  return this.replace(/Ä/g,'A').replace(/Ö/g,'O').replace(/Ü/g,'U');
}; 
function alphabetic(str1, str2) {
  var a = str1.toUpperCase().removeUmlauts();
  var b = str2.toUpperCase().removeUmlauts();
  return a < b ? -1 : a > b ? 1 : 0;
}

在分析可能出现的字符并决定如何处理它们之后,您可以在其中添加其他映射,例如replace(/Æ/gi, 'Ae')。删除变音符号(例如,将 É 映射到 E)很简单,但通常足够好,而且肯定比让实现来决定 É 是否在 Z 之后更好。至少你会在不同的实现中得到一致的结果,你会看到什么出现问题并需要修复,而不是等待其他用户抱怨您的代码排序错误(在他们的环境中)。

【讨论】:

  • 谢谢 - 很好的答案和链接。我将放弃 localeCompare 并转向您所描述的内容。
最近更新 更多