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.



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.


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.


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)")
}

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 })

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 }))


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
}

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]
}

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 })

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"]

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]

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.


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]


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

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"]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.