Je sais que ce sujet a déjà été discuté mais je ne peux pas résoudre d'autres réponses, donc désolé d'avance pour mon développement!
J'ai besoin de trier ce dictionnaire par clés
codeValueDict = ["us": "$", "it": "€", "fr": "€"]
donc j'ai besoin d'un dictionnaire comme celui-ci
sortedDict = ["fr": "€", "it": "€", "us": "$"]
mais je ne peux pas faire ça.
J'ai essayé ça
let sortedKeysAndValues = sorted(dictionary) { $0.0 < $1.0 }
mais après j'ai besoin de créer deux tableaux de ce dictionnaire (clés et valeurs) et, en utilisant cette solution
codesArray = sortedKeysAndValues.keys.array
donnez-moi l'erreur '[(String, String)]' n'a pas de membre nommé 'keys' car cette solution ne renvoie pas exactement un dictionnaire.
J'ai donc essayé une autre solution:
let prova = codiceNomeDict as NSDictionary
for (k,v) in (Array(codiceNomeDict).sorted {$0.1 < $1.1}) {
let value = "[\"\(k)\": \"\(v)\"]"
println(value)
}
Ce qui fonctionne bien, mais je ne sais pas comment créer un nouveau dictionnaire de value s.
Quelle est la meilleure solution? Comment le faire fonctionner?
La sortie de la fonction sorted
ci-dessus est un Array . Donc, vous ne pouvez pas obtenir les clés et les valeurs comme un Dictionnaire . Mais vous pouvez utiliser la fonction map
pour récupérer ces clés et valeurs triées
Retourne un tableau contenant les éléments triés de
source
{selon} . L'algorithme de tri n'est pas stable (peut changer l'ordre relatif de Éléments pour lesquels isOrderedBefore n'établit pas d'ordre).
let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
let sortedArray = sorted(codeValueDict, {$0.0 < $1.0})
print(sortedArray)
let keys = sortedArray.map {return $0.0 }
print(keys)
let values = sortedArray.map {return $0.1 }
print(values)
Les dictionnaires ne sont pas commandés. Si vous voulez énumérer ces éléments dans l’ordre, vous pouvez le faire en utilisant la solution de @ HoaParis (qui est ma préférence), ou
for (k,v) in sorted(codiceNomeDict, {$0.1 < $1.1}) { ... }
ce qui est juste un peu mieux que ce que vous faisiez auparavant car il ne génère pas de tableau temporaire.
Mais si vous voulez vraiment "une collection qui mappe une valeur à une autre et qui soit ordonnée par sa clé", vous devez créer une autre structure de données pour cela. Alors faisons ça. C'est une bonne expérience d'apprentissage.
Cette version implémente simplement SequenceType
et fournit un indice get/set, qui correspond à la plupart de ce que vous souhaiteriez généralement. En faire un CollectionType
complet est un peu pénible à mon avis, puisque startIndex
et endIndex
doivent être O (1). Possible; juste plus que ce que je veux faire ce matin.
Notez l'ajout majeur de Key: Comparable
. C'est pourquoi Dictionary
ne peut pas être commandé. Il n'y a aucune promesse que vous pouvez trier leurs clés. En ajoutant cette exigence, nous pouvons le faire.
struct SortedDictionary<Key: Hashable, Value where Key: Comparable>: SequenceType {
private var dict: Dictionary<Key, Value>
init(_ dict: Dictionary<Key, Value>) {
self.dict = dict
}
func generate() -> GeneratorOf<(Key, Value)> {
let values = Array(Zip(self.dict.keys, self.dict.values))
.sorted {$0.0 < $1.0 }
return GeneratorOf(values.generate())
}
subscript(key: Key) -> Value? {
get { return self.dict[key] }
set(value) { self.dict[key] = value }
}
}
var codeValueDict = ["us": "$", "it": "€", "fr": "€"]
var sortedDict = SortedDictionary(codeValueDict)
for (k, v) in sortedDict {
println("\(k) => \(v)")
}
sortedDict["us"]
sortedDict["ab"] = "!"
sortedDict
Pourquoi voudriez-vous vous embêter avec SortedDictionary
alors que vous avez déjà sorted()
? En général, je ne le ferais pas. Mais cela offre des opportunités d'abstraction. Vous pouvez contrôler l'ordre de tri lors de la création d'un objet plutôt que lors de son énumération. Vous pouvez potentiellement mettre en cache l'ordre de tri (bien que je soupçonne que dans la plupart des cas, cela fera mal plutôt que d'aider).
Mais je recommande simplement d’utiliser sorted
en général.
Swift n'inclut pas un type de dictionnaire trié et les dictionnaires ne peuvent pas être triés. Vous pouvez ajouter une extension proposant le tri à [(Key, Value)]
en procédant comme suit:
extension Dictionary {
func sort(isOrderedBefore: (Key, Key) -> Bool) -> [(Key, Value)] {
var result: [(Key, Value)] = []
let sortedKeys = keys.array.sorted(isOrderedBefore)
for key in sortedKeys {
result.append(key, self[key]!)
}
return result
}
}
Trier vos clés en fonction de la valeur du dictionnaire est en réalité plus simple qu'il n'y parait au début:
let yourDict = ["One": "X", "Two": "B", "Three": "Z", "Four": "A"]
let sortedKeys = yourDict.keys.sort({ (firstKey, secondKey) -> Bool in
return yourDict[firstKey] < yourDict[secondKey]
})
Et c'est tout! Il n'y a vraiment rien de plus.
Vous ne pouvez pas trier le dictionnaire aussi facilement. Je pense que le dictionnaire utilise une sorte de structure de données arborescente. Mais après le tri, vous obtenez un tableau de tuples. Ainsi, vous pouvez obtenir les clés de la manière suivante:
let codeValueDict = ["us": "$", "it": "€", "fr": "€"]
let sortedKeysAndValues = sorted(codeValueDict) { $0.0 < $1.0 }
let keys = sortedKeysAndValues.map {$0.0 }
let values = sortedKeysAndValues.map {$0.1 }
Voici une fonction qui renvoie un tableau de clés triées par respectant la casse (ou toute valeur de chaîne).
N'oubliez pas que la structure des données du dictionnaire Swift ne peut pas être stockée, triée par clé dans la mémoire. Alors oui, vous pouvez le trier par clé, mais si vous l’imprimez par exemple, l’ordre des touches est à nouveau aléatoire.
/// returns an array of values sorted by values case-insensitive
func sortCaseInsensitive(values:[String]) -> [String]{
let sortedValues = values.sort({ (value1, value2) -> Bool in
if (value1.lowercaseString < value2.lowercaseString) {
return true
} else {
return false
}
})
return sortedValues
}
Appeler avec
let dict = ["world": "Hello!", "foo": "bar", "zYeah": "a", "akey": "xval"]
let sortedKeys = sortCaseInsensitive(Array(dict.keys))