设为首页 加入收藏

TOP

深入理解苹果系统(Unicode)字符串的排序方法(二)
2019-08-31 00:21:37 】 浏览:75
Tags:深入 理解 苹果 系统 Unicode 字符串 排序 方法
t;]; //1. 默认排序方式 NSArray *defaultedSortedArray = [rawArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { return [obj1 compare:obj2 options:NSCaseInsensitiveSearch]; }]; __block NSMutableArray *codeUnits = [NSMutableArray array]; [defaultedSortedArray enumerateObjectsUsingBlock:^(NSString* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [codeUnits addObject:@([obj characterAtIndex:0])]; }]; NSLog(@"默认Unicode码点值排序 %@ 对应的各个字符串的首字符码点值是 %@", [defaultedSortedArray descriptionWithLocale:cnLocal], codeUnits);

输出结果是

排序结果 
 ..  123  @  AA  abb  abc  μ  язык  ?  ?  一生一世  上  爱你 
 对应的各个字符串的首字符码点值是 
 46  49  64  65  97  97  956  1103  12928  12964  19968  19978  29233 

我们常用的各种字符的码点值范围是:

  • 0-9 U+0030 - U0039
  • a-z U+0061 - U+007A
  • A-Z U+0041 - U+005A 具体可通过:unicode-table查询。

UCA 默认排序

在我们前面下载的文件CLDR库有个/common/uca/allkeys_CLDR.txt文件,它表示我们指定locale为“en”或者说是默认的排序规则。它的格式是

0000  ; [.0000.0000.0000] # <NULL>
0001  ; [.0000.0000.0000] # <START OF HEADING>
0002  ; [.0000.0000.0000] # <START OF TEXT>
0003  ; [.0000.0000.0000] # <END OF TEXT>

分号前的值表示码点,分号后中括号里面的值表示UCA算法权重,用.号来区分,Unicode字符就是按照这个规则从上到下排序。

NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
defaultedSortedArray = [rawArray sortedArrayUsingComparator:^NSComparisonResult(NSString*  _Nonnull obj1, NSString*  _Nonnull obj2) {
    return [obj1 compare:obj2 options:0 range:NSMakeRange(0, obj1.length) locale:enLocale];
}];
NSLog(@"默认排序规则或者指定地区为locale后的排序结果是 %@", [defaultedSortedArray descriptionWithLocale:cnLocal]);

排序结果是

默认排序规则或者指定地区为en后的排序结果是 
 ..  (ch  (en  @  123  AA  abb  abc  μ  язык  ?  一生一世  上  ?  爱你 

这种排序依次为符号,数字,英文/汉字等script charaters。

CLDR调整后的排序

在下载的CLDR文件中,有个common/bcp47/collation.xml文件,列出了可选的排序方式,有standard,pinyin, stroke(笔画排序)等。

img排序可选方式

那如何确定各个区域语言下,该使用哪种排序规则呢,我们可以看到common/collation/文件夹下,有很多标记语言LDML文件,这些文件就是表示在不同区域语言下,采用的排序规则。

img

我们打开zh.xml,这个就是我们简体中文的排序规则,可以看到,里面默认采用的排序是pinyin排序,并且在开头还写了各个声调字母的排序先后顺序。

img

  1. 首先按照pinyin声调的先后顺序进行排序,即zh.xml底下列出的先后顺序进行排序。
  2. 如果是在同一行的汉字,则按照笔画由少到多的顺序进行排序。
  3. 如果还不能区分大小,就按照kRSUnicode (偏旁索引的方式,按照康熙字典的定义)的先后顺序进行排序。

假如我们指定区域为zh_CN,则对于字符串中出现的中文则排在其他语言字符串前面。其他script charater则按照allkeys_CLDR.txt的顺序进行进行排序。值得注意的是,中文由于多音字,在这里不一定能够完全按照我们的习惯排序正确,比如“重逢(chong feng)”就没有第一个拼音chong去排,而是按照zhong来排列的。

默认排序规则或者指定地区为zh_CN后的排序结果是 
 ..  (ch  (en  @  0124  123  艾你  爱你  産  上  ?  ?  一生一世  重逢  重要  aa  AA  abb  μ  язык 
 
 默认排序规则或者指定地区为ru_CN后的排序结果是 
 ..  (ch  (en  @  0124  123  язык  aa  AA  abb  μ  ?  一生一世  上  ?  爱你  産  艾你  重要  重逢 
 

至此,我们大致讲清楚了几种排序规则。

苹果系统的排序

前面我们已经说了,苹果系统的NSString排序是UCA和CLDR规则的。NSString提供了很多的排序方法,但最终,所有的都是调用了compare:options:range:locale:来进行处理,只是传入的参数不同。可以在NSString.swift 中查看具体的实现。这么多排序方法中,其中之一是localizedStandardCompare:, 这个方法是苹果系统推荐的,在给用户展示的列表数据的名字或者其他字符串进行排序时所使用的方法。我们看到,它的内部实现是

   public func localizedStandardCompare(_ string: String) -> ComparisonResult {
        return compare(string, options: [.caseInsensitive, .numeric, .widthInsensitive, .forcedOrdering], range: NSRange(location: 0, length: length), locale: Locale.current._bridgeToObjectiveC())
    }

其中用到的四个Options参数是

NSCaseInsensitiveSearch  //大小写不敏感
NSNumericSearch //对字符串中出现的数字字符进行数字化的大小比较,比如Foo2.txt < Foo7.txt < Foo25.txt
NSWidthInsensitiveSearch //忽略宽度,按照实际表示的意思来对比,如'a' = UFF41
NSForcedOrderingSearch //强制返回Ascending或者Descending,和NSCaseInsen
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇虹软人脸识别iOS SDK2.0 下一篇【OC底层】Category、+load方法、..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目