Swift中的字符串和字符比较对区域设置敏感是什么意思?

时间:2014-09-07 19:30:21

标签: swift string

我开始学习Swift语言,我很好奇Swift中的字符串和字符比较对语言环境不敏感是什么意思?这是否意味着所有字符都以UTF-8字符存储在Swift中?

3 个答案:

答案 0 :(得分:23)

(现在为Swift 3更新了所有代码示例。)

将Swift字符串与<进行比较会进行字典比较 基于所谓的"Unicode Normalization Form D"(可以使用 decomposedStringWithCanonicalMapping

例如,分解

"ä" = U+00E4 = LATIN SMALL LETTER A WITH DIAERESIS

是两个Unicode代码点的序列

U+0061,U+0308 = LATIN SMALL LETTER A + COMBINING DIAERESIS

出于演示目的,我编写了一个小的String扩展名来转储 String的内容作为Unicode代码点数组:

extension String {
    var unicodeData : String {
        return self.unicodeScalars.map {
            String(format: "%04X", $0.value)
            }.joined(separator: ",")
    }
}

现在让我们拿一些字符串,用<对它们进行排序:

let someStrings = ["ǟψ", "äψ", "ǟx", "äx"].sorted()
print(someStrings)
// ["a", "ã", "ă", "ä", "ǟ", "b"]

并转储每个字符串的Unicode代码点(原始和分解 form)在排序数组中:

for str in someStrings {
    print("\(str)  \(str.unicodeData)  \(str.decomposedStringWithCanonicalMapping.unicodeData)")
}

输出

äx  00E4,0078  0061,0308,0078
ǟx  01DF,0078  0061,0308,0304,0078
ǟψ  01DF,03C8  0061,0308,0304,03C8
äψ  00E4,03C8  0061,0308,03C8

很好地表明比较是通过Unicode的词典排序完成的 分解形式的代码点。

对于多个字符的字符串也是如此,如下例所示 显示。与

let someStrings = ["ǟψ", "äψ", "ǟx", "äx"].sorted()

上述循环的输出是

äx  00E4,0078  0061,0308,0078
ǟx  01DF,0078  0061,0308,0304,0078
ǟψ  01DF,03C8  0061,0308,0304,03C8
äψ  00E4,03C8  0061,0308,03C8

这意味着

"äx" < "ǟx", but "äψ" > "ǟψ"

(这对我来说至少是意料之外的事。)

最后,让我们将其与区域设置敏感的排序进行比较,例如瑞典语:

let locale = Locale(identifier: "sv") // svenska
var someStrings = ["ǟ", "ä", "ã", "a", "ă", "b"]
someStrings.sort {
    $0.compare($1, locale: locale) == .orderedAscending
}

print(someStrings)
// ["a", "ă", "ã", "b", "ä", "ǟ"]

如您所见,结果与Swift <排序不同。

答案 1 :(得分:1)

更改区域设置可以更改字母顺序,例如区分大小写的比较因区域设置而显得不区分大小写,或者更一般地说,两个字符串的字母顺序不同。

答案 2 :(得分:1)

词典排序和区域敏感排序可能不同。你可以在这个问题中看到它的一个例子: Sorting scala list equivalent to C# without changing C# order

在特定情况下,区域设置敏感的排序在_之前放置1,而在词典排序中则相反。

Swift比较使用词典排序。