O que significa que as comparações de caracteres e de caracteres no Swift não são sensíveis ao código de idioma?

Comecei a aprender a linguagem Swift e estou muito curioso. O que significa que as comparações de caracteres e de caracteres no Swift não são sensíveis ao código de idioma? Isso significa que todos os personagens são armazenados em caracteres Swift como UTF-8?

(Todos os exemplos de código atualizados para o Swift 3 agora.)

Comparando strings Swift com < faz uma comparação lexicográfica baseada no chamado "Unicode Normalization Form D" (que pode ser calculado com decomposedStringWithCanonicalMapping )

Por exemplo, a decomposição de

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

é a sequência de dois pontos de código Unicode

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

Para fins de demonstração, escrevi uma pequena extensão String que despeja o conteúdo da String como uma matriz de pontos de código Unicode:

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

Agora vamos pegar algumas strings, classificá-las com < :

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

e despejar os pontos de código Unicode de cada seqüência de caracteres (no formulário original e decomposto) na matriz classificada:

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

A saída

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

mostra bem que a comparação é feita por um ordenamento lexicográfico dos pontos de código Unicode no formulário decomposto.

Isso também é verdadeiro para sequências de mais de um caractere, como mostra o exemplo a seguir. Com

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

a saída do loop acima é

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

o que significa que

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

(que foi pelo menos inesperado para mim).

Finalmente, vamos comparar isso com uma ordenação sensível ao local, por exemplo, sueco:

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

Como você pode ver, o resultado é diferente da sorting < Swift < .

Alterar a localidade pode alterar a ordem alfabética, por exemplo, uma comparação com distinção entre maiúsculas e minúsculas pode parecer insensível a maiúsculas e minúsculas devido à localidade ou, em geral, a ordem alfabética de duas cadeias é diferente.

O pedido lexicográfico e o ordenamento sensível ao código do idioma podem ser diferentes. Você pode ver um exemplo disso nesta pergunta: Classificando uma lista de scala equivalente a C # sem alterar a ordem C #

Nesse caso específico, o ordenamento sensível ao código de idioma colocado antes de 1 , enquanto que em um ordenamento lexicográfico é o oposto.

A comparação rápida usa ordenação lexicográfica.