Sortuj słownik według kluczy

128

Chcę posortować słownik w języku Swift. Mam słownik taki jak:

"A" => Array[]
"Z" => Array[]
"D" => Array[]

itd. Chcę, żeby tak było

"A" => Array[]
"D" => Array[]
"Z" => Array[]

itp.

Wypróbowałem wiele rozwiązań na SO, ale nikt dla mnie nie pracował. Używam XCode6 Beta 5 i na nim niektórzy dają błąd kompilatora, a niektóre rozwiązania dają wyjątki. Więc każdy, kto może opublikować kopię roboczą sortowania słownikowego.

Aleem Ahmad
źródło
6
Nie możesz sortować słownika, to kontener asocjacyjny. Jeśli potrzebujesz określonej kolejności, skopiuj klucze do tablicy i posortuj je. Następnie iteruj po kluczach i ściągnij odpowiadające im wartości.
dasblinkenlight
@dasblinkenlight Czy możesz mi powiedzieć, jak szybko posortować tablicę?
Aleem Ahmad
@AleemAhmad Spójrz na tę odpowiedź , ma sortedKeysfunkcję.
dasblinkenlight,
@dasblinkenlight Próbowałem tego, ale powoduje to błąd na [KeyType]
Aleem Ahmad,

Odpowiedzi:

167
let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(<) // ["A", "D", "Z"]

EDYTOWAĆ:

Posortowana tablica z powyższego kodu zawiera tylko klucze, podczas gdy wartości muszą być pobierane z oryginalnego słownika. Jednak 'Dictionary'jest również 'CollectionType'parami of (klucz, wartość) i możemy użyć 'sorted'funkcji globalnej, aby uzyskać posortowaną tablicę zawierającą zarówno klucze, jak i wartości, na przykład:

let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
println(sortedKeysAndValues) // [(A, [1, 2]), (D, [5, 6]), (Z, [3, 4])]

EDIT2: Preferowana jest obecnie składnia Swift zmieniająca się co miesiąc

let sortedKeys = Array(dictionary.keys).sort(<) // ["A", "D", "Z"]

Globalny sortedjest przestarzały.

Ivica M.
źródło
To daje tablicę kluczy. W tablicy brakuje wartości. Chyba możesz sprawdzić wartości w słowniku.
StilesCrisis
2
Masz rację. Właśnie zredagowałem ten post, aby zapewnić rozwiązanie umożliwiające uzyskanie tablicy par (klucz, wartość) posortowanych według kluczy. Dziękuję za komentarz.
Ivica M.
@IvicaM. Witaj! Zrozumiałem, jak mogę sortować słownik według kluczy, ale nie rozumiem, jak mogę sortować tablicę elementów w słowniku. Proszę pomóż mi. Na przykład prywatne kontakty var: [(String, [User])] = []
Alexander Khitev,
5
Swift 3 = Array (Dictionary.keys) .sorted (by: <)
miff
4
Od wersji Swift 4 możesz pisaćlet sortedKeys = dictionary.keys.sorted()
Code Different
113

Swift 2.0

Zaktualizowana wersja odpowiedzi Ivica M:

let wordDict = [
     "A" : [1, 2],
     "Z" : [3, 4],
     "D" : [5, 6]
]

let sortedDict = wordDict.sort { $0.0 < $1.0 }
print("\(sortedDict)") // 

Szybki 3

wordDict.sorted(by: { $0.0 < $1.0 })

Ogłoszenie:

Nie zdziw się, że wynikowy typ jest tablicą, a nie słownikiem. Nie można sortować słowników ! Wynikowy typ danych to posortowana tablica, tak jak w odpowiedzi @ Ivica.

Dan Beaulieu
źródło
26
to faktycznie zwraca tablicę [(String, [Int])] nie a Dictionary
scord
4
zrealizowane Słowniki są nieposortowane, więc i tak nie ma sensu ponownie tworzyć typu danych. Skończyło się na tym, że zapisałem tablicę posortowanych kluczy.
scord
I dostać Binary operator > can not be compared to two Any` argumentów. Downcasting też nie działa
Sean
27

Jeśli chcesz iterować zarówno po kluczach, jak i wartościach w kolejności posortowanej według kluczy, ten formularz jest dość zwięzły

let d = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

for (k,v) in Array(d).sorted({$0.0 < $1.0}) {
    println("\(k):\(v)")
}
rks
źródło
posortowane jest metoda niestandardowa lub co? pokazuje błąd podczas wdrażania
rikky
@rikkyG Swift 1: sorti sorted. Swift 2: sortstał się sortInPlacei sortedstał się sort.
Eric Aya
14

W Swift 4 możesz napisać to mądrzej:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })
Davide Gianessi
źródło
3
Dzięki za wysiłek, ale przede wszystkim „let” nie powoduje kompilacji kodu, więc najpierw musi to być „var”. Następnie po pomyślnej kompilacji ten kod nie działa, nie sortuje słownika. Otrzymuję ten sam wynik przed i po uruchomieniu tego kodu. Może czegoś mi brakuje, ale proszę rozwinąć więcej lub zmienić kod. ======= var d = [1: "cześć", 2: "cześć", -1: "foo"] print (d) - >>> drukuje [2: "pa", -1: " foo ", 1:" hello "] d = [Int: String] (uniqueKeysWithValues: d.sorted {$ 0.key <$ 1.key}) print (d) - >>> drukuje [2:" bye ", -1 : "foo", 1: "hello"]
KarimIhab
Nie jest to możliwe, ponieważ po konwersji z powrotem do słownika zmieni się na kolekcję nieuporządkowaną, ponieważ słowniki w języku swift są kolekcjami nieuporządkowanymi developer.apple.com/documentation/swift/dictionary
Jaimin
12

Wypróbowałem wszystkie powyższe, w skrócie wszystko, czego potrzebujesz, to

let sorted = dictionary.sorted { $0.key < $1.key }
let keysArraySorted = Array(sorted.map({ $0.key }))
let valuesArraySorted = Array(sorted.map({ $0.value }))

Elsammak
źródło
6

W przypadku Swift 4 zadziałały następujące rozwiązania:

let dicNumArray = ["q":[1,2,3,4,5],"a":[2,3,4,5,5],"s":[123,123,132,43,4],"t":[00,88,66,542,321]]

let sortedDic = dicNumArray.sorted { (aDic, bDic) -> Bool in
    return aDic.key < bDic.key
}
Shiv Kumar
źródło
5
To nie zwraca Dictionary, to zwraca tablicę krotki
Daniel Arantes Loverde
@DanielArantesLoverde Słowniki z definicji nie nadają się do sortowania. Zestaw krotek to najlepsze, co możesz zrobić.
John Montgomery
1
Wiem o tym, ale pytanie proszę o zamówione, więc ta odpowiedź nie jest poprawna. Czy sie zgadzasz?
Daniel Arantes Loverde
6

To elegancka alternatywa dla sortowania samego słownika:

Od wersji Swift 4 i 5

let sortedKeys = myDict.keys.sorted()

for key in sortedKeys {
   // Ordered iteration over the dictionary
   let val = myDict[key]
}
ThunderStruct
źródło
5

W Swift 5 , aby posortować słownik według KEYS

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.0 < $1.0 })

Aby posortować słownik według WARTOŚCI

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.1 < $1.1 })
Abdul Karim Khan
źródło
4

W przypadku języka Swift 3 poniższe sortowanie zwraca słownik posortowany według kluczy:

let unsortedDictionary = ["4": "four", "2": "two", "1": "one", "3": "three"]

let sortedDictionary = unsortedDictionary.sorted(by: { $0.0.key < $0.1.key })

print(sortedDictionary)
// ["1": "one", "2": "two", "3": "three", "4": "four"]
Arijan
źródło
10
To nie zwróci słownika, zwróci tablicę
krotek
Nawet nie czytaj pytania przed udzieleniem odpowiedzi. Marnujesz tutaj czas wielu ludzi. To pytanie dotyczy w szczególności sortowania słownika i uzyskiwania posortowanego słownika, a nie tablicy. Nie wiem, dlaczego wszyscy podają złe odpowiedzi.
Shivam Pokhriyal,
3

„posortowane” w iOS 9 i xcode 7.3, Swift 2.2 jest niemożliwe, zmień „sort” na „sort”, na przykład:

let dictionary = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]
let sortedKeysAndValues = Array(dictionary).sort({ $0.0 < $1.0 })
print(sortedKeysAndValues)

//sortedKeysAndValues = ["desert": 2.99, "main course": 10.99, "salad": 5.99]
AmyNguyen
źródło
3
Wynik sortKeysAndValues ​​nie jest słownikiem, to tablica!
Kanał
2
Wynikiem jest Arrayof Tuples, a nieDictionary
2

Szybki 5

Wprowadź słownik, który chcesz posortować alfabetycznie według kluczy.

// Sort inputted dictionary with keys alphabetically.
func sortWithKeys(_ dict: [String: Any]) -> [String: Any] {
    let sorted = dict.sorted(by: { $0.key < $1.key })
    var newDict: [String: Any] = [:]
    for sortedDict in sorted {
        newDict[sortedDict.key] = sortedDict.value
    }
    return newDict
}

dict.sorted (by: {$ 0.key <$ 1.key}) przez siebie zwraca krotkę (wartość, wartość) zamiast słownika [wartość: wartość]. W ten sposób pętla for analizuje krotkę, aby powrócić jako słownik. W ten sposób umieszczasz słownik i odzyskujesz słownik.

Krekin
źródło
2

Swift 4 i 5

W przypadku sortowania kluczy ciągów:

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

Przykład:

var dict : [String : Any] = ["10" : Any, "2" : Any, "20" : Any, "1" : Any]

dictionary.keys.sorted() 

["1" : Any, "10" : Any, "2" : Any, "20" : Any]

dictionary.keys.sorted(by: {$0.localizedStandardCompare($1) == .orderedAscending})

["1" : Any, "2" : Any, "10" : Any, "20" : Any]

Xav Mac
źródło
1

W przypadku Swift 3 działały u mnie następujące rzeczy, a składnia Swift 2 nie działała:

// menu is a dictionary in this example

var menu = ["main course": 10.99, "dessert": 2.99, "salad": 5.99]

let sortedDict = menu.sorted(by: <)

// without "by:" it does not work in Swift 3
Joeri
źródło
Ta odpowiedź jest dość niekompletna. Co to jest sortedDict? Co to jest menu? Ten kod również nie wydaje się być prawidłowy.
random_user_name,
Coś poważniejszego: słownik nie ma porządku . To, co otrzymujesz za pomocą swojego kodu, to tablica krotek, a nie posortowany słownik - jak już zostało powiedziane w niektórych odpowiedziach i komentarzach.
Eric Aya
temat to: sortuj słownik po klawiszach, odpowiadam na ten temat. I jest to specyficzna uwaga dotycząca jedynie zmiany składni w Swift 3, nie zaprzecza temu, co zostało napisane wcześniej.
Joeri
"Ta odpowiedź jest dość niekompletna. Co to jest sortDict? Co to jest menu? Ten kod też nie wydaje się być poprawny. - cale_b" Odpowiedź została zredagowana, jedyne czego brakowało to deklaracja dictionaty - menu. Pomyślałem, że to jasne, chodzi tylko o zmianę składni w Swift 3, jak wskazano. Kod działa w Swift 3.
Joeri
jakaś sugestia na szybkie 4 plz?
famfamfam
1

Swift 3 jest posortowany (według: <)

let dictionary = [
    "A" : [1, 2],
    "Z" : [3, 4],
    "D" : [5, 6]
]

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
Shadros
źródło