设为首页 加入收藏

TOP

深入理解苹果系统(Unicode)字符串的排序方法(三)
2019-08-31 00:21:37 】 浏览:77
Tags:深入 理解 苹果 系统 Unicode 字符串 排序 方法
sitiveSearch结合起来就是例如"aaa" > "AAA"

并且指定了当前的区域locale作为参数,这就相当于指定使用CLDR进行排序,如果是在手机上,这个方法的调用和系统当前的区域设置是有很大关系的,这和我们代码中设置locale是一个道理。我们可以这样理解,调用这个方法得到的结果和在iOS Files中文件名选择按照名称排序得到的结果是一样的。在iOS中,当我们的区域设置为中国时,排序顺序就是 标点符号等特殊符号>数字>中文>英文等其他

img区域设置成中文后的排序

自此,对localizedStandardCompare:的使用,大家应该比较清楚了。

数字的比较

这里单独把数字字符串的比较列出来,是因为一些人对这里比较迷惑。由于localizedStandardCompare:中有使用NSNumericSearch选项,这里简单来说,就是假如目前两个字符串是相等的,两者都出现了数字,则分别从两者种取出这段数字进行数字化来比较大小,按照数字大小排序。为了验证这里的逻辑,我看了下CFString.cCFStringCompareWithOptionsAndLocale这个方法的实现,这个就是compare实际调用的的比较方法。其中关于数字大小比较的代码如下:

if (numerically && ((0 == strBuf1Len) && (str1Char <= '9') && (str1Char >= '0')) && ((0 == strBuf2Len) && (str2Char <= '9') && (str2Char >= '0'))) { // If both are not ASCII digits, then don't do numerical comparison here
        uint64_t intValue1 = 0, intValue2 = 0;  // !!! Doesn't work if numbers are > max uint64_t
        CFIndex str1NumRangeIndex = str1Index;
        CFIndex str2NumRangeIndex = str2Index;

        do {
            intValue1 = (intValue1 * 10) + (str1Char - '0');
            str1Char = CFStringGetCharacterFromInlineBuffer(&inlineBuf1, ++str1Index);
        } while ((str1Char <= '9') && (str1Char >= '0'));

        do {
            intValue2 = intValue2 * 10 + (str2Char - '0');
            str2Char = CFStringGetCharacterFromInlineBuffer(&inlineBuf2, ++str2Index);
        } while ((str2Char <= '9') && (str2Char >= '0'));

        if (intValue1 == intValue2) {
            if (forceOrdering && (kCFCompareEqualTo == compareResult) && ((str1Index - str1NumRangeIndex) != (str2Index - str2NumRangeIndex))) {
                compareResult = (((str1Index - str1NumRangeIndex) < (str2Index - str2NumRangeIndex)) ? kCFCompareLessThan : kCFCompareGreaterThan);
                numericEquivalence = true;
                forcedIndex1 = str1NumRangeIndex;
                forcedIndex2 = str2NumRangeIndex;
            }

            continue;
        } else if (intValue1 < intValue2) {
            if (freeLocale && locale) {
                CFRelease(locale);
            }
                return kCFCompareLessThan;
            } else {
                if (freeLocale && locale) {
                    CFRelease(locale);
                }
                return kCFCompareGreaterThan;
        }
    }

这段代码的含义就是,如果两个字符串都是以数字开始(也可能是字符串前面都相等,当前从数字部分开始比较),则取出两个字符串的数字,按照数字大小进行对比。如果数字能够比较出大小,则直接返回两个字符串的大小关系,不再对后面的字符串进行对比。比如“0123aaa” 和“1bbbbbbbbb”,就直接返回“0123aaa”大于“1bbbbbbbbb”。当然,这里取出的数字可能超出了uint64_t表示的最大值,但是这种概率很低,在我们的名称排序中,很难遇到这么长的数字进行比较的。明白这个规则后,大家对字符串中出现的数字在进行排序时应该比较理解了。下面的名字排序是对着的。

img

综述

本文主要讲述由localizedStandardCompare:这个苹果系统方法所引发的对排序规则的深入研究,简单来说,设置中选择区域为中国时,排序顺序为 标点符号等特殊符号>数字>中文>英文等其他。中文本身是按照pinyin排序的,只是由于多音字的关系,不能够做到100%按照中文习惯来排序,会有些无法正确排序的问题,但大体已经符合我们的习惯了。

参考

https://zh.wikipedia.org/wiki/Unicode

https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFStrings/Articles/UnicodeBasis.html

https://www.objc.io/issues/9-strings/unicode/

http://unicode.org/reports/tr10/

https://www.cnblogs.com/huahuahu/p/Unicode-zi-fu-chuan-pai-xu-gui-ze-yi-ru-he-que-din.html

https://raw.githubusercontent.com/larvit/larvitgeodata/master/cldrData/common/uca/allkeys_CLDR.txt

http://cldr.unicode.org/

相关阅读
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇虹软人脸识别iOS SDK2.0 下一篇【OC底层】Category、+load方法、..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目