排序在非字母(即亚洲)语言中意味着什么?

时间:2010-09-21 20:37:12

标签: javascript arrays sorting unicode

我有一些代码按对象属性对表列进行排序。我想到,在日语或中文(非字母语言)中,发送到sort函数的字符串将按照字母语言的方式进行比较。

以日本姓氏列表为例:

寿拘 (Suzuki)
松坂 (Matsuzaka)
松井 (Matsui)
山田 (Yamada)
藤本 (Fujimoto)

当我通过Javascript对上面的列表进行排序时,结果是:

寿拘 (Suzuki)
山田 (Yamada)
松井 (Matsui)
松坂 (Matsuzaka)
藤本 (Fujimoto)

这与日语syllabary的排序不同,日语{{3}}将按照发音方式排列列表(日语字典的方式):

寿拘 (Suzuki)
藤本 (Fujimoto)
松井 (Matsui)
松坂 (Matsuzaka)
山田 (Yamada)

我想知道的是:

  1. 在排序函数中是否真的将一个双字节字符与另一个字节进行比较?
  2. 真正发生了什么?
  3. (额外信用)这种结果是否意味着什么呢?排序的概念真的适用于亚洲(和其他)语言吗?如果是这样,它是什么意思,应该为创建这些语言的比较函数而努力?

  4. 总结回答并提出结论:

    首先,感谢所有为讨论作出贡献的人。这提供了非常丰富的信息和帮助。特别关注 bobince Lie Ryan Gumbo Jeffrey Zheng Larry K < / strong>,进行深入细致的分析。我将复选标记给了 Larry K ,因为我指的是我的问题无法预见的解决方案,但我找到了我认为有用的每个答案。

    协商一致似乎是:

    1. 中文和日文字符串按Unicode代码点排序,它们的排序可能基于一个理论基础,这个理论基础可能对知识渊博的读者有一定的理解,但在帮助用户方面可能没有多大实际价值找到他们正在寻找的信息。

    2. 在语义上或语音上有用的那种比较函数的种类考虑过于繁琐,特别是因为结果可能不太令人满意,并且在任何情况下比较算法都会必须为每种语言进行更改。最好只是为了在不尝试比较功能的情况下进行排序。

    3. 我可能在这里提出错误的问题。也就是说,我在考虑“真正的问题”并没有考虑如何使排序在这些语言中有用,但我如何为用户提供在列表中查找项目的有用方法。西方人自动想到为此目的排序,我对此感到内疚。 Larry K向我指出一篇维基百科的文章,该文章暗示过滤功能可能对亚洲读者更有用。这就是我打算追求的目标,因为它至少和排序一样快,客户端。我将保留列排序,因为它在西方语言中很好理解,并且因为任何语言的发言者都会发现日期和其他基于数字的数据类型的排序很有用。但我还将添加过滤机制,这对于任何语言的长列表都很有用。

9 个答案:

答案 0 :(得分:23)

  

在排序函数中,是否真的可以将一个双字节字符与另一个字节进行比较?

JavaScript中的原生String类型基于UTF-16代码单元,这就是比较的内容。对于Basic Multilingual Plane中的字符(所有这些都是),这与Unicode代码点相同。

像Shift-JIS这样的编码这样的术语“双字节”在Web上下文中没有意义:DOM和JavaScript字符串本身就是Unicode,浏览器收到的编码页面中的原始字节很久就消失了。

  

这种结果是否意味着什么呢?

小。 Unicode代码点并不声称提供任何特定的排序......因为 没有全局接受的排序。即使对于ASCII拉丁字符的最基本情况,语言也不一致(例如,vw是否是相同的字母,或i的大写是Iİ)。而且CJK比这更有趣。

主要的Unicode CJK统一表意文字区块碰巧按行数和笔画数(康熙字典顺序)排序,这可能非常有用。但是使用来自任何其他CJK扩展块的字符,或者混合使用某些假名或者romaji,并且它们之间没有任何有意义的排序。

Unicode Consortium do attempt用于定义一些通用排序规则,但它很复杂,通常不会在语言级别尝试。真正需要语言敏感排序能力的系统(例如操作系统,数据库)往往有自己的整理方案。

  

这与日语音节的排序不同

是。除了校对问题之外,通过音节准确处理汉字是一项非常困难的任务,因为你必须猜测发音。 JavaScript无法真实地知道,'藤本',你的意思是'藤本',而不是'touhon';这种事情需要深入的内置词典和仍然不可靠的启发式...而不是你想要用编程语言构建的那种东西。

答案 1 :(得分:10)

如果你想要比字符串的默认JS排序更好的东西,你可以在Javascript中实现Unicode Collation Algorithm。可能会改善一些事情。虽然Unicode文档声明:

  

整理不统一;它有所不同   根据语言和文化:   德国人,法国人和瑞典人排序   相同的字符不同。有可能   也因具体应用而异:   即使在同一种语言中,   字典可能有不同的排序   电话簿或书籍索引。对于   非字母脚本,如East   亚洲象形文字,整理可以   无论是语音还是基于   这个角色的外表。

Wikipedia article指出,由于在非字母脚本中整理是非常困难的,现在一天的答案是通过输入字符来查找信息非常容易,而不是通过查看列表。

我建议您与应用程序中真正知识渊博的最终用户交谈,看看他们最喜欢的行为方式。订购中文字符的问题并非您的应用所独有。

此外,如果您不想在系统中实现排序规则,则可以使用另一种解决方案来创建将名称存储在MySql或其他数据库中的Ajax服务,然后使用订单语句查找数据。

答案 2 :(得分:3)

字符串逐字符比较code point value defines the order

  

字符串的比较在代码点值的序列上使用简单的字典顺序。没有尝试使用Unicode规范中定义的字符或字符串相等和整理顺序的更复杂,语义导向的定义。因此,根据Unicode标准规范相等的字符串可以测试为不相等。实际上,该算法假设两个字符串都已经处于规范化形式。

如果您需要更多,则需要使用字符串比较,可以将整理考虑在内。

答案 3 :(得分:3)

其他人已经回答了其他问题,我会接受这个问题:

  

创造一个人应该努力的目标   比较这些语言的功能?

一种方法是,您需要创建一个可以“读取”字符的程序;也就是说,能够将hanzi / kanji字符映射到他们的“声音”(拼音/平假名阅读)。在最简单的层面上,这意味着将hanzi / kanji映射到声音的数据库。当然这比听起来更困难(双关语并不打算),因为很多角色在不同的语境中可以有不同的发音,而中文有许多不同的方言需要考虑。

另一种方式,是按笔顺顺序排序。这意味着需要有一个数据库将hanzi / kanji映射到他们的笔画。另一个问题:中国人和日本人在不同的笔画顺序中写道然而,除了日语和中文的区别之外,使用笔画排序在单个文本中更加一致,因为汉字/汉字字符几乎总是使用相同的笔画顺序书写,而不管它们的含义或读取方式。类似的想法是按部首而不是简单的笔划顺序排序。

第三种方式是按Unicode代码点排序。这很简单,并且始终提供无可争议的一致排序;然而,问题是排序顺序对人类毫无意义。

最后一种方法是重新考虑绝对排序的必要性,并使用一些启发式方法来根据用户的需要进行排序。例如,在购物车软件中,您可以根据用户的购买习惯或价格进行排序。这样可以避免这个问题,但大部分时间都可以使用(除非您正在编译字典)。

正如您所注意到的,前两种方法需要创建一对多映射的庞大数据库,但它们仍然不能始终提供有用的结果。第三种方法也需要一个庞大的数据库,但许多编程语言已经将这个数据库内置到该语言中。最后一种方法是一些启发式方法,可能是最有用的,但它们注定永远不会给出一致的排序(比前两种方法更差)。

答案 4 :(得分:1)

是的,人物会被比较。它们通常根据它们的Unicode代码点进行比较,但在平假名和汉字之间有很大的不同 - 这使得日语中的排序可能无用。 (汉字借用了中文,但他们用中文出现的顺序与平方代表相同含义的顺序不一致)。为了比较的目的,有一些排序可以使一些角色“相等”,但我不知道是否有人会认为汉字相当于包含其发音的平假名 - 特别是因为一个角色可以有很多不同的发音。

中文或韩文,或其他没有3种不同字母的语言(其中一种非常不规则),它可能不是一个问题。

答案 5 :(得分:1)

这些按代码点值升序排序。对于人类读者来说,这当然毫无意义。为日语设计一个明智的分类方案并非不可能,但是对汉字进行排序很难(部分原因是我们不一定知道我们是在看日语还是中文),而且很多程序员都试图解决这个问题。

答案 6 :(得分:1)

许多编程语言中的常规字符串比较函数旨在确保将字符串排序为唯一顺序,以允许二进制搜索和重复检测等算法正常工作。要以对人类读者有意义的方式对数据进行排序,必须知道数据代表什么。例如,在英文电影标题列表中,“El Mariachi”通常在“E”下排序,但在西班牙电影标题列表中,它将在“M”下排序。应用程序将需要除字符串本身之外的信息,以了解字符串应如何排序。

答案 7 :(得分:1)

对于中国人(从大陆的角度来看)Q1的答案(可以排序)和Q3(有点有意义)都是“是”。对于Q2(如何排序):

所有汉字都有明确的发音(有些是复音),如pinyin中所定义的那样,它更常见(如几乎所有的中文词典),用拼音排序,没有歧义。然后按笔画顺序对具有相同发音的字符进行排序。

复调字符对排序提出了额外的挑战,因为他们的拼音通常取决于他们所在的单词(我听说日语字符可能更加多毛)。例如,字符A在阿姨(括号中的音调)中发音为a(1),在阿胶中发音为e(1)。因此,如果您需要对单词或句子进行排序,则不能简单地从每个项目中一次查看一个字符。

答案 8 :(得分:0)

回想一下,在JavaScript中,您可以将sort()函数传递给您自己实现排序的函数,以实现对人类重要的排序:

myarray.sort(function(a,b){

//return 0, 1, or -1 based on the comparison of the two strings

});