2017-05-11 9 views
1

Ich verwende eine for-Schleife, um eine Zeichenfolge aus Schlüsseln und Werten zu erstellen. Leider verhält sich swift auf Mac und Linux anders.Schnell, wie man Diktatschlüssel nach Bytewert und nicht alphabetisch sortiert?

for key in parameters.keys.sorted() {...}

Ich möchte meine Schlüssel von Byte-Wert sortieren, nicht alphabetisch, sollten Klein Parameter nach Groß diejenigen aufgelistet.

Also ein Schlüssel wie "AWT" sollte vor einem Schlüssel wie "Ast" kommen.

+1

Auf Apple-Plattformen erhalten Sie die gewünschte Bestellung erhalten. Unter Linux, das ein bekannter Fehler ist, der in Swift 4 behoben werden sollte, siehe https://bugs.swift.org/browse/SR-530. - Beachten Sie, dass dies nichts mit Wörterbüchern oder Schlüsseln zu tun hat, sondern nur, wie der Vergleich von Strings durchgeführt wird, "print ([" AWT "," Ast "]. Sorted())' reicht aus, um den Unterschied zwischen Apple und Linux. –

+0

.sorted() kann Parameter "mit dem gegebenen Prädikat als Vergleich zwischen Elementen sortiert" verwenden. Gibt es eine Möglichkeit, die richtige Sortierung manuell zu erreichen? – Leo

+0

Vielleicht sollten Sie zuerst klären, was "sort by byte value" für Sie genau bedeutet. –

Antwort

3

Auf Apple-Plattformen, ist Swift Strings Vergleich ein lexikographischer Vergleich von Unicode skalaren Werten, basierend auf der "Unicode-Normalisierungs Form D" so genannten, How String Comparison happens in Swift oder What does it mean that string and character comparisons in Swift are not locale-sensitive? für Details.

Unter Linux ist die Sortierreihenfolge unterschiedlich. Das ist ein bekanntes Problem ([String] sort order varies on Darwin vs. Linux) und soll 4.

in Swift festgelegt werden, wenn Sie nur über ASCII-Zeichen sorgen dann ein möglicher Ansatz wäre sein, die UTF-8-Darstellung der Saiten zu vergleichen:

func utf8StringCompare(s1: String, s2: String) -> Bool { 
    let u1 = s1.utf8 
    let u2 = s2.utf8 
    for (x, y) in zip(u1, u2) { 
     if x < y { return true } 
     if x > y { return false } 
    } 
    return u1.count < u2.count 
} 


let s = ["AWT", "Ast"].sorted(by: utf8StringCompare) 
print(s) // ["AWT", "Ast"] 

Dies ergibt identische Ergebnisse auf Apple-Plattformen und unter Linux.

Beachten Sie jedoch, dass dies die nicht die Standardsortierreihenfolge für Swift Strings auf Apple-Plattformen ist. So replizieren, dass auf Linux (bevor es in Swift 4 festgelegt ist), würde der folgende Algorithmus arbeiten:

func unicodeStringCompare(s1: String, s2: String) -> Bool { 
    let u1 = s1.decomposedStringWithCanonicalMapping.unicodeScalars 
    let u2 = s2.decomposedStringWithCanonicalMapping.unicodeScalars 
    for (x, y) in zip(u1, u2) { 
     if x.value < y.value { return true } 
     if x.value > y.value { return false } 
    } 
    return u1.count < u2.count 
} 

let someStrings = ["a", "b", "e", "f", "ä", "é"].sorted(by: unicodeStringCompare) 
print(someStrings) // ["a", "ä", "b", "e", "é", "f"] 
+0

ausgezeichnete Antwort, vielen Dank – Leo

Verwandte Themen