Trier le dictionnaire par valeurs dans Swift
y a - t-il des clés analogiques de - (NSArray *)transmises par le secteur de comparaison de valeur:(SEL)dans swift?
Comment faire cela sans casting à NSDictionary?
j'ai essayé, mais il semble que ce ne soit pas une bonne solution.
var values = Array(dict.values)
values.sort({
>
})
for number in values {
for (key, value) in dict {
if value == number {
println(key + " : (value)");
dict.removeValueForKey(key);
break
}
}
}
Exemple:
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
dict.sortedKeysByValues(>) // fanta (12), cola(10), sprite(8)
14 réponses
Essaie:
let dict = ["a":1, "c":3, "b":2]
extension Dictionary {
func sortedKeys(isOrderedBefore:(Key,Key) -> Bool) -> [Key] {
return Array(self.keys).sort(isOrderedBefore)
}
// Slower because of a lot of lookups, but probably takes less memory (this is equivalent to Pascals answer in an generic extension)
func sortedKeysByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] {
return sortedKeys {
isOrderedBefore(self[]!, self[]!)
}
}
// Faster because of no lookups, may take more memory because of duplicating contents
func keysSortedByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] {
return Array(self)
.sort() {
let (_, lv) =
let (_, rv) =
return isOrderedBefore(lv, rv)
}
.map {
let (k, _) =
return k
}
}
}
dict.keysSortedByValue(<)
dict.keysSortedByValue(>)
mise à Jour:
mise à jour de la syntaxe du tableau et de la sémantique de tri de beta 3. Notez que j'utilise sort
et non sorted
pour minimiser la copie des tableaux. Le code pourrait être rendu plus compact, en regardant la version antérieure et en remplaçant sort
sorted
et réparer le KeyType[]
[KeyType]
mise à jour de Swift 2.2:
types changés de KeyType
Key
et ValueType
Value
. Utilisé de nouvelles sort
intégré Array
au lieu de sort(Array)
Remarque: les performances de l'ensemble de ces pourrait être légèrement améliorée par l'utilisation de sortInPlace
au lieu de sort
Vous pouvez utiliser quelque chose comme ceci peut-être:
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
var myArr = Array(dict.keys)
var sortedKeys = sort(myArr) {
var obj1 = dict[] // get ob associated w/ key 1
var obj2 = dict[] // get ob associated w/ key 2
return obj1 > obj2
}
myArr // ["fanta", "cola", "sprite"]
cela devrait vous donner les clés triées en fonction de la valeur, et est un peu plus propre:
var sortedKeys = Array(dict.keys).sorted({dict[] < dict[]})
juste un code de ligne pour trier le dictionnaire par des valeurs dans Swift 4:
let sortedByValueDictionary = myDictionary.sorted { .1 < .1 }
je pense que c'est la façon la plus facile de trier le dictionnaire Swift par valeur.
let dict = ["apple":1, "cake":3, "banana":2]
let byValue = {
(elem1:(key: String, val: Int), elem2:(key: String, val: Int))->Bool in
if elem1.val < elem2.val {
return true
} else {
return false
}
}
let sortedDict = dict.sort(byValue)
trier vos clés par la valeur du dictionnaire est en fait plus simple qu'il n'y paraît 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. Je n'ai pas encore trouvé une méthode plus rapide.
Beaucoup de réponses, voici un one-liner. Je l'aime parce qu'il fait plein usage de fonctions natives et itératives Swift et n'utilise pas de variables. Cela devrait aider l'optimiseur de faire sa magie.
return dictionary.keys.sort({ < }).flatMap({ dictionary[] })
notez l'utilisation de flatMap, car la souscription d'un dictionnaire renvoie une valeur optionnelle. En pratique, cela ne devrait jamais revenir à zéro puisque nous obtenons la clé du dictionnaire lui-même. flatMap
est-il que pour s'assurer que le résultat n'est pas un tableau d'options. Si votre tableau est associé la valeur doit ÊTRE une option que vous pouvez utiliser map
à la place.
OneLiner :
let dict = ["b":2,"a":1,"c":3]
(Array(dict).sorted{.1 < .1}).forEach{(k,v) in print("\(k):\(v)")}
//Output: a:1, b:2, c:3
changer .forEach
.map
-> programmation Fonctionnelle
sucre Syntaxique :
extension Dictionary where Value:Comparable {
var sortedByValue:[(Key,Value)] {return Array(self).sorted{.1 < .1}}
}
extension Dictionary where Key:Comparable {
var sortedByKey:[(Key,Value)] {return Array(self).sorted{.0 < .0}}
}
["b":2,"a":1,"c":3].sortedByKey//a:1, b:2, c:3
["b":2,"a":1,"c":3].sortedByValue//a:1, b:2, c:3
il suffit de le lancer à NSDictionary et ensuite appeler la méthode. N'importe où vous utilisez @selector
dans ObjC vous pouvez simplement utiliser une chaîne de caractères dans Swift. Donc, il devrait ressembler à ceci:
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
let sortedKeys = (dict as NSDictionary).keysSortedByValueUsingSelector("compare:")
ou
let sortedKeys2 = (dict as NSDictionary).keysSortedByValueUsingComparator
{
( as NSNumber).compare( as NSNumber)
}
A partir de Swift 3, pour trier vos clés en fonction des valeurs, la liste ci-dessous semble prometteuse:
var keys = Array(dict.keys)
keys.sortInPlace { (o1, o2) -> Bool in
return dict[o1]! as! Int > dict[o2]! as! Int
}
ce qui suit peut être utile si vous voulez la sortie d'un tableau de paires clé-valeur sous la forme d'un tuple, triés par valeur.
var dict = ["cola" : 10, "fanta" : 12, "sprite" : 8]
let sortedArrByValue = dict.sorted{.1 > .1}
print(sortedArrByValue) // output [(key: "fanta", value: 12), (key: "cola", value: 10), (key: "sprite", value: 8)]
la façon suivante dans Swift 3 trié mon dictionnaire par valeur dans l'ordre croissant:
for (k,v) in (Array(dict).sorted {.1 < .1}) {
print("\(k):\(v)")
}
SWIFT 3:
en utilisant quelques ressources, j'ai rassemblé ce code magnifiquement court.
dictionary.keys.sorted{dictionary[]! < dictionary[]!}
renvoie un tableau des clés du dictionnaire triées par leurs valeurs. Il fonctionne parfaitement et ne jette pas d'erreurs lorsque le dictionnaire est vide. Essayez ce code dans un terrain de jeu:
//: Playground - noun: a place where people can play
import UIKit
let dictionary = ["four": 4, "one": 1, "seven": 7, "two": 2, "three": 3]
let sortedDictionary = dictionary.keys.sorted{dictionary[]! < dictionary[]!}
print(sortedDictionary)
// ["one", "two", "three", "four", "seven"]
let emptyDictionary = [String: Int]()
let emptyDictionarySorted = emptyDictionary.keys.sorted{emptyDictionary[]! < emptyDictionary[]!}
print(emptyDictionarySorted)
// []
si vous voulez de l'aide sur pourquoi diable le code utilise 0$, 1 $et n'a même pas les parenthèses après la méthode "trié", consultez ce post - https://stackoverflow.com/a/34785745/7107094
C'est comme ça que je l'ai fait - trier dans ce cas par une clé appelée position. Essayez ceci dans une aire de jeux:
var result: [[String: AnyObject]] = []
result.append(["name" : "Ted", "position": 1])
result.append(["name" : "Bill", "position": 0])
result
result = sorted(result, positionSort)
func positionSort(dict1: [String: AnyObject], dict2: [String: AnyObject]) -> Bool {
let position1 = dict1["position"] as? Int ?? 0
let position2 = dict2["position"] as? Int ?? 0
return position1 < position2
}