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)
18
demandé sur Gabriele Petronella 2014-06-07 00:19:15

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 sortsorted et réparer le KeyType[][KeyType]

mise à jour de Swift 2.2:

types changés de KeyTypeKey et ValueTypeValue. 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

19
répondu David Berry 2016-05-31 22:54:17

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"]
20
répondu Logan 2014-06-06 21:56:59

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[]})
14
répondu pulse4life 2017-08-05 22:54:23

juste un code de ligne pour trier le dictionnaire par des valeurs dans Swift 4:

    let sortedByValueDictionary = myDictionary.sorted { .1 < .1 }
9
répondu S.S.D 2018-04-30 10:29:55

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)
7
répondu jeongmin.cha 2015-11-05 13:40:40

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.

5
répondu Martin 2015-10-27 04:34:15

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.

5
répondu Ash 2016-06-14 15:22:25

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
4
répondu eonist 2017-06-21 20:55:39

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) 
                  }
3
répondu ahruss 2014-06-09 03:03:36

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
}
3
répondu judepereira 2016-06-11 17:28:20

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)]
3
répondu cypher 2017-06-17 22:43:09

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)")
}
1
répondu Darius Miliauskas 2017-03-17 15:29:24

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

1
répondu Trev14 2017-08-05 19:13:19

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
}
0
répondu Codezy 2015-04-13 23:14:44