Trier le dictionnaire par clés

128

Je veux trier un dictionnaire dans Swift. J'ai un dictionnaire comme:

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

etc. Je veux que ce soit comme

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

etc.

J'ai essayé de nombreuses solutions sur SO mais personne n'a fonctionné pour moi. J'utilise XCode6 Beta 5 et certains donnent des erreurs de compilation et certaines solutions donnent des exceptions. Donc, quiconque peut publier la copie de travail du tri du dictionnaire.

Aleem Ahmad
la source
6
Vous ne pouvez pas trier un dictionnaire, c'est un conteneur associatif. Si vous avez besoin d'un ordre particulier, copiez les clés dans un tableau et triez-les. Ensuite, parcourez les clés et tirez leurs valeurs correspondantes.
dasblinkenlight
@dasblinkenlight Alors pouvez-vous me dire comment trier un tableau en swift?
Aleem Ahmad
@AleemAhmad Jetez un œil à cette réponse , elle a une sortedKeysfonction.
dasblinkenlight
@dasblinkenlight J'ai essayé ceci mais cela donne une erreur sur [KeyType]
Aleem Ahmad

Réponses:

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

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

ÉDITER:

Le tableau trié à partir du code ci-dessus contient uniquement des clés, tandis que les valeurs doivent être extraites du dictionnaire d'origine. Cependant, 'Dictionary'est également une 'CollectionType'paire de (clé, valeur) et nous pouvons utiliser la 'sorted'fonction globale pour obtenir un tableau trié contenant à la fois des clés et des valeurs, comme ceci:

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

EDIT2: La syntaxe Swift changeante mensuellement préfère actuellement

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

Le global sortedest obsolète.

Ivica M.
la source
Cela vous donne un tableau des clés. Le tableau n'a pas les valeurs. Vous pouvez rechercher les valeurs dans le dictionnaire, je suppose.
StilesCrisis
2
Vous avez raison. Je viens de modifier l'article pour fournir une solution pour obtenir un tableau de paires (clé, valeur) triées par clés. Merci pour le commentaire.
Ivica M.
@IvicaM. salut! J'ai compris comment trier le dictionnaire par clés, mais je ne comprends pas comment puis-je trier un tableau d'éléments dans le dictionnaire. Aidez-moi, s'il vous plaît. Par exemple, les contacts var privés: [(String, [User])] = []
Alexander Khitev
5
Swift 3 = Array (dictionary.keys) .sorted (by: <)
miff
4
À partir de Swift 4, vous pouvez écrirelet sortedKeys = dictionary.keys.sorted()
Code Different
113

Swift 2.0

Version mise à jour de la réponse d'Ivica M:

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

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

Swift 3

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

Remarquer:

Ne soyez pas surpris que le type résultant soit un tableau plutôt qu'un dictionnaire. Les dictionnaires ne peuvent pas être triés ! Le type de données résultant est un tableau trié, tout comme dans la réponse de @ Ivica.

Dan Beaulieu
la source
26
cela renvoie en fait un tableau de [(String, [Int])] pas un dictionnaire
scord
4
réalisé que les dictionnaires ne sont pas triés, il est donc inutile de recréer le type de données de toute façon. J'ai fini par enregistrer un tableau de clés triées.
scord
Je reçois Binary operator > can not be compared to two Any` opérandes. Downcasting ne fonctionne pas non plus
Sean
27

Si vous souhaitez parcourir à la fois les clés et les valeurs dans un ordre trié par clé, ce formulaire est assez succinct

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
la source
trié est la méthode personnalisée ou quoi? il affiche une erreur lors de la mise en œuvre
rikky
@rikkyG Swift 1: sortet sorted. Swift 2: sortest devenu sortInPlaceet sortedest devenu sort.
Eric Aya
14

Dans Swift 4, vous pouvez l'écrire plus intelligemment:

let d = [ 1 : "hello", 2 : "bye", -1 : "foo" ]
d = [Int : String](uniqueKeysWithValues: d.sorted{ $0.key < $1.key })
Davide Gianessi
la source
3
Merci pour l'effort, mais avant tout, le "let" ne fait pas construire le code, donc il doit d'abord être "var". Ensuite, après la compilation, ce code ne fonctionne pas, il ne trie pas le dictionnaire.J'obtiens le même résultat avant et après l'exécution de ce code. Il me manque peut-être quelque chose, mais veuillez préciser davantage ou modifier le code. ======= var d = [1: "bonjour", 2: "bye", -1: "toto"] print (d) - >>> affiche [2: "bye", -1: " toto ", 1:" hello "] d = [Int: String] (uniqueKeysWithValues: d.sorted {$ 0.key <$ 1.key}) print (d) - >>> affiche [2:" bye ", -1 : "foo", 1: "hello"]
KarimIhab
Ce n'est pas possible, car lorsque vous le reconvertissez en dictionnaire, il passera à la collection non ordonnée car les dictionnaires de swift sont une collection non ordonnée developer.apple.com/documentation/swift/dictionary
Jaimin
12

J'ai essayé tout ce qui précède, en un mot, tout ce dont vous avez besoin est

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

Elsammak
la source
6

Pour Swift 4, ce qui suit a fonctionné pour moi:

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
la source
5
Cela ne renvoie pas de dictionnaire, cela renverra un tableau de tuples
Daniel Arantes Loverde
@DanielArantesLoverde Les dictionnaires ne sont pas triables par définition. Un tableau de tuples est le mieux que vous puissiez faire.
John Montgomery
1
Je le sais, mais la question demande une commande, donc cette réponse n'est pas correcte. Êtes-vous d'accord?
Daniel Arantes Loverde
6

C'est une alternative élégante au tri du dictionnaire lui-même:

À partir de Swift 4 et 5

let sortedKeys = myDict.keys.sorted()

for key in sortedKeys {
   // Ordered iteration over the dictionary
   let val = myDict[key]
}
ThunderStruct
la source
6

Dans Swift 5 , afin de trier le dictionnaire par CLÉS

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

Afin de trier le dictionnaire par VALEURS

let sortedYourArray = YOURDICTIONARY.sorted( by: { $0.1 < $1.1 })
Abdul Karim Khan
la source
4

Pour Swift 3, le tri suivant renvoie le dictionnaire trié par clés:

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
la source
10
Cela ne retournera pas de dictionnaire, cela retournera un tableau de tuples
anoop4real
Ne lisez même pas la question avant de mettre votre réponse. Vous perdez du temps à beaucoup de gens ici. Cette question concerne spécifiquement le tri d'un dictionnaire et l'obtention d'un dictionnaire trié et non d'un tableau. Je ne sais pas pourquoi tout le monde donne de mauvaises réponses.
Shivam Pokhriyal
3

"trié" dans iOS 9 et xcode 7.3, swift 2.2 est impossible, remplacez "trié" par "tri", comme ceci:

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
la source
3
Le résultat de sortedKeysAndValues ​​n'est pas un dictionnaire, c'est un tableau!
Chaîne
2
Le résultat est un Arrayde Tuples, pas unDictionary
2

Swift 5

Saisissez votre dictionnaire que vous souhaitez trier par ordre alphabétique par touches.

// 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 (par: {$ 0.key <$ 1.key}) par lui-même renvoie un tuple (valeur, valeur) au lieu d'un dictionnaire [valeur: valeur]. Ainsi, la boucle for analyse le tuple à renvoyer en tant que dictionnaire. De cette façon, vous mettez un dictionnaire et récupérez un dictionnaire.

Krekin
la source
2

Swift 4 et 5

Pour le tri des clés de chaîne:

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

Exemple:

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
la source
1

Pour Swift 3, ce qui suit a fonctionné pour moi et la syntaxe Swift 2 n'a pas fonctionné:

// 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
la source
Cette réponse est assez incomplète. C'est quoi sortedDict? C'est quoi menu? Ce code ne semble pas non plus valide.
random_user_name
Quelque chose de plus grave maintenant: un dictionnaire n'a pas d'ordre . Ce que vous obtenez avec votre code est un tableau de tuples, pas un dictionnaire trié - comme déjà dit dans certaines réponses et commentaires.
Eric Aya
le sujet est: trier le dictionnaire par clés, je réponds à ce sujet. Et c'est une remarque spécifique concernant uniquement un changement de syntaxe dans Swift 3, cela ne nie rien de ce qui a été écrit auparavant.
Joeri
"Cette réponse est assez incomplète. Qu'est-ce que sortedDict? Qu'est-ce que menu? Ce code ne semble pas non plus valide. - cale_b" La réponse a été éditée, la seule chose qui manquait était une déclaration pour une dictionaty - menu. Je pensais que c'était clair, il ne s'agit que d'un changement de syntaxe dans Swift 3 comme indiqué. Le code fonctionne dans Swift 3.
Joeri
une suggestion pour swift 4 plz?
famfamfam
1

Swift 3 est trié (par: <)

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

let sortedKeys = Array(dictionary.keys).sorted(by:<) // ["A", "D", "Z"]
Shadros
la source