Cosa significa che i confronti tra stringhe e caratteri in Swift non sono sensibili alle impostazioni internazionali?

Ho iniziato a imparare il linguaggio Swift e sono molto curioso. Che cosa significa che i confronti tra stringhe e caratteri in Swift non sono sensibili alle impostazioni internazionali? Significa che tutti i personaggi sono memorizzati in Swift come i caratteri UTF-8?

(Tutti gli esempi di codice aggiornati per Swift 3 ora.)

Confrontando le stringhe Swift con < fa un confronto lessicografico basato sulla cosiddetta "Normalizzazione modulo Unicode D" (che può essere calcasting con decomposedStringWithCanonicalMapping )

Ad esempio, la decomposizione di

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

è la sequenza di due punti di codice Unicode

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

A scopo dimostrativo, ho scritto una piccola estensione String che scarica il contenuto della String come una serie di punti di codice Unicode:

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

Ora prendiamo alcune stringhe, ordinali con < :

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

e scaricare i punti di codice Unicode di ogni stringa (nella forma originale e decomposta) nell'array ordinato:

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

Il risultato

 ä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 chiaramente che il confronto è fatto da un ordinamento lessicografico dei punti di codice Unicode nella forma scomposta.

Questo vale anche per stringhe di più di un carattere, come mostra il seguente esempio. Con

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

l'uscita del ciclo sopra è

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

che significa che

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

(che era almeno inaspettato per me).

Infine confrontiamo questo con un ordinamento sensibile alle impostazioni internazionali, ad esempio in svedese:

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

Come vedi, il risultato è diverso da Swift < ordinamento.

La modifica delle impostazioni locali può modificare l’ordine alfabetico, ad esempio un confronto con distinzione tra maiuscole e minuscole può apparire senza distinzione tra maiuscole e minuscole a causa delle impostazioni internazionali o, più in generale, l’ordine alfabetico delle due stringhe è diverso.

L’ordinamento lessicografico e l’ordinamento sensibile alle impostazioni internazionali possono essere diversi. Puoi vedere un esempio in questa domanda: Ordinare la scala lista equivalente a C # senza modificare l’ordine C #

In quel caso specifico l’ordinamento sensibile alla localizzazione colloca _ prima di 1 , mentre in un ordinamento lessicografico è il contrario.

Il confronto rapido usa l’ordinamento lessicografico.