Flash Player中的flash.globalization包(part8):比较和排序

排序(collation)是比较元素(elements)以确定它们是等价的,或者一个逻辑上应当排在其他后面的过程。当应用到文本时,排序在两种情况下特别地有用:

  1. 当您需要确定两个文本字段是否足够等价以保证返回一个,当另一个被搜索时;或者避免在数据库中非法复制
  2. 当您需要对用户要浏览的一个集合中的单词或句子进行排序,以便使他们可以快速定位到它们希望选择的条目上

文化敏感的排序

字母、词和句子的排序习惯(practice)对于下列情况是非常重要的:目录、词典、索引簿(例如,电话号码本)、列表框或者下拉列表,以及其他很多目的。排序规则直接关系到所使用的书写系统,并且不同地区间有或多或少的差异。

几个书写系统拥有关于等价(equivalence)的共同类。例如,欧洲字母表普遍地在很大程度上将大写字母(majuscules)(大写字母,比如A、B、C等)和对应的小写字母(minuscules)(小写字母,比如a、b、c等)认为是等价的,因此在顺序列表中会放在一起。在法语中,虽然变音符(diacritical marks)(比如ê中的抑扬音符号(circumflex accent))是拼写(有时候是发音)相关的,但是在排序时它们被赋予了几乎相同的权值(所以,ê、é、èë被认为和普通的字母e是几乎等价的)。在日语中,人们同样可能会选择将平假名(Hiragana)(あ、い、う等)和片假名(Katakana)(ア、イ、ウ等)字符当作是基本等价的。

一个字符在不同的语言间,也可能会有不同的发音或有不同的功能,而且有可能影响其在排序时的位置。例如,在法语和英语中ö(带有分音符(dieresis)的字母o)被认为基本上等价于普通的字母o,但是在瑞典语中则会排在字母z之后。

最后,即使在一个社群(community)中,特别的排序方式也可能会被用于不同的情况。在德国,电话簿传统上将元音变音(比如ö)等价于字母e紧随的那个普通字母(如在oe中)。但是,德语字典不使用这种等价关系。在日本,字典可能使用基于以下方式的词序进行排序:发音,或者偏旁(出现在很多字中的图形)和笔画,或者甚至基于语义的值(具有相似意思的一组词)。

当对将提交给用户的可视的列表进行排序时,必须按照用户的期望进行。这不仅是一个美学的问题:期待其在列表的末尾,一个瑞典用户可能完全无法找到一个以ö开头的元素,如果它被放在了普通字母o开头的元素之后的话。幸运的是,避免这个问题是很简单的:使用为用户区域所配置的flash.globalization排序程序对列表进行排序。

匹配VS搜索

要正确地使用一个排序程序(collator)明确您的目标是必不可少:您是否尝试确定您是否匹配了一个模式(pattern)和一个候选者(candidate),或者您是否正在构建一个将显示给用户的元素的有序列表?

匹配通常在用户搜索一个项目时被执行(例如,在文档中搜索一个单词)。当进行匹配时,您可能想忽略一些小的差异,以便提高发现相关匹配项的机会。例如,大小写通常是被忽略的。变音符(Diacritical marks)也常常被忽略,因为并不是所有的用户按预期的那样输入它们(或者因为他们的键盘布局使得输入很难,或者是一个拼写错误的结果)。很多拉丁字符和日本字还存在半角(half-width)和全角(full-width)形式。这不是一个显示风格的问题(字体或其他可视化属性):而是,每种形式在字符集中都有不同的代码点(code point)(数值(numeric value))。一个日本用户搜索“Helloリンリン”(半角)时,非常可能也想找到,“Helloリンリン”(全角)也。

当排序时,另一方面,除非您想把看起来十分相似的条目(entries)当作不想要的复制品(unwanted duplicates),输入列表中的每个项通常都会出现在排好的列表中,并且获得可预测的顺序(order)(给定的区域)需要使用一个算法,该算法尽可能地避免出现等价的情况,以一致的方式处理任何的不同。大写字符可能是没有被给予多大的分量,但它仍然会被考虑。

Collator类允许您选择哪些元素(elements)将被视为重要的。为了使事情简单,它也允许您在实例化排序程序(collator)时指定一个通用的操作模式:CollatorMode.MATCHING和CollatorMode.SORTING,将以一种适合期望的操作类型的方式来配置collator所有相关的设置。.

保持中立的优点

正如我在导言中所说,文化敏感的操作只为人类用户的利益而存在。如果您正在考虑为加快数据库查询或避免在一个主键字段重复而排序,那么永远使用中立的排序顺序,保证在所有平台上产生相同的结果。一个简单的二进制比较可能适合这些目的。在某些情况下,您可能需要对文本进行标准化(normalize)以避免由于图形类似的字符或是由于Unicode已分解的形式(Unicode decomposed forms)造成的near-duplicates。

使用Collator类

再一次,首先创建服务对象,这一次是Collator类的实例。和往常一样,您必须指定一个区域标识符。

如之前的解释,您可以(而且应该)也指定一个通用操作模式:CollatorMode.SORTING(默认模式,建立一个将呈现给用户的有序列表的理想模式)或CollatorMode.MATCHING。(对这样的情况是有用的:匹配用户可能会寻找相同的文本的片断,例如在搜索时):
import flash.globalization;  var collator:Collator = new  Collator(selectedLocale, CollatorMode.SORTING);

同使用格式化器一样,如果平台不完全支持您所指定的区域,那么一个备用的区域可能已被选择。您可以在创建对象之后通过立即测试Collator类的lastOperationStatus属性检查这是否发生了。如果它显示LastOperationStatus.NO_ERROR以外的任何其他,那么检查actualLocaleIDName属性的值找出哪个区域被当作备用了。关于备用的描述详见“选择一个区域(Selecting a locale)”一节。

现在您可以使用Collator类的两个主要方法之一了。如果您的目的是对一个列表进行排序(collator被实例化为 CollatorMode.SORTING),那么使用compare()方法:

  1. var comparisonResult:Integer = collator.compare("Hello ","Hello ");
  2. if(comparisonResult < 0) {
  3. //第一个字符串在第二个前面。
  4. } else if(comparisonResult > 0) //第一个字符串在第二个后面。
  5. } else {
  6. //comparisonResult是零:两个字符串被认为是相同的。
  7. }

如果您只是试图找出是否匹配(collator被实例化为CollatorMode.MATCHING),那么您可以简单地使用equals()方法,它返回一个布尔值:
  1.  
  2. var matchResult:Boolean = collator.equals("Hello リンリン","Hello リンリン");
  3. if(matchResult) { //两个字符串被认为是相同的。 } else { //不匹配。 }

自定义的Collator

您可以通过设置collator的几个属性来微调它的行为。例如,将其设置为忽略大小写的差异(设置ignoreCase属性为true),但是将变音符号视为一种不同的因素(设置ignoreDiacritics属性为false)。把这些设置暴露在您的应用程序的用户界面上,将使得用户在开始一个搜索时按他们喜欢的方式调整它们。否则,安全的做法是简单地依靠排序模式(实例化collator时指定的)以适当的方式来配置collator。

numericComparison属性是这个规则中的一个有趣的例外。设置其为true导致collator考虑在文本嵌入的数的值,而不是它们的文本表示。例如:

  1. collator.numericComparison = true;
  2. var numericComparisonResult:Integer = collator.compare("Hello 10","Hello 2"); collator.numericComparison = false;
  3. var textualComparisonResult:Integer = collator.compare("Hello 10","Hello 2");

在上面的例子中,numericComparisonResult将得到一个正的值,表示“Hello 10”在“Hello 2”之后,因为考虑到10的数值大于2。相比之下,textualComparisonResult将得到一个负值,表示“Hello 10”在“Hello 2”之前,因为考虑到在排序顺序中字符“1”在字符“2”之前。

再一次,请记住,不同的操作系统在实现此功能时可能是不同的,特别是关于它们是否能处理小数或负值和各种不同的数族。

上一页(Par7) / 下一页(Par9)

riadevID: 
您给予的分值: None 平均分: 10 (1 vote)

发表新评论

  • 网页地址和电子邮件地址将会被自动转换为链接。
  • 行和段被自动切分。
  • 您可以使用下面的标签来高亮显示您的评论内容: <code>, <blockcode>. 可以使用"[foo]".旁边显示标签样式 "<foo>" PHP代码可以用这样的区块来包含<?php ... ?> or <% ... %>

更多格式化选项信息

验证区域
系统验证:请回答下面的问题