2015-05-25 15 views
9

Ich versuche, ein Swift-Array, das aus Wörterbüchern besteht, zu sortieren. Ich habe unten ein Arbeitsbeispiel vorbereitet. Ziel ist es, das gesamte Array mit dem Element "d" in den Wörterbüchern zu sortieren. Ich habe dieses Arbeitsbeispiel vorbereitet, die in ein Swift-Projekt gelegt werden können:Sortieren Swift Array von Wörterbüchern nach Wert eines Schlüssels

var myArray = Array<AnyObject>() 
var dict = Dictionary<String, AnyObject>() 

dict["a"] = "hickory" 
dict["b"] = "dickory" 
dict["c"] = "dock" 
dict["d"] = 5 

myArray.append(dict) 

dict["a"] = "three" 
dict["b"] = "blind" 
dict["c"] = "mice" 
dict["d"] = 6 

myArray.append(dict) 

dict["a"] = "larry" 
dict["b"] = "moe" 
dict["c"] = "curly" 
dict["d"] = 2 

myArray.append(dict) 

println(myArray[0]) 
println(myArray[1]) 
println(myArray[2]) 
} 

Diese in das Protokoll in der folgenden Ausgabe führt:

{ 
    a = hickory; 
    b = dickory; 
    c = dock; 
    d = 5; 

} 
{ 
    a = three; 
    b = blind; 
    c = mice; 
    d = 6; 
} 
{ 
    a = larry; 
    b = moe; 
    c = curly; 
    d = 2; 
} 

Das Ziel ist es, die Anordnung der „d zu sortieren "(d‚Element, so dass der obige Ausgang in dem folgenden geändert werden würde, die auf numerischer Reihenfolge der basiert‘:‚2, 5, 6‘):

{ 
    a = larry; 
    b = moe; 
    c = curly; 
    d = 2; 
} 
{ 
    a = hickory; 
    b = dickory; 
    c = dock; 
    d = 5; 
} 
{ 
    a = three; 
    b = blind; 
    c = mice; 
    d = 6; 
} 

es einige andere Fragen, die ähnlich scheinen aber wenn du klügst Bei ihnen wird klar, dass sie das nicht ansprechen. Vielen Dank für Ihre Hilfe.

Antwort

15

zu erklären, wenn Sie es als ANYOBJECT halten müssen, müssen Sie explizit Stimmen:

var myArray = Array<AnyObject>() 
var dict = Dictionary<String, AnyObject>() 

dict["a"] = ("hickory" as! AnyObject) 
dict["b"] = ("dickory" as! AnyObject) 
dict["c"] = ("dock" as! AnyObject) 
dict["d"] = (6 as! AnyObject) 

myArray.append(dict as! AnyObject) 

dict["a"] = ("three" as! AnyObject) 
dict["b"] = ("blind" as! AnyObject) 
dict["c"] = ("mice" as! AnyObject) 
dict["d"] = (5 as! AnyObject) 


myArray.append(dict as! AnyObject) 

dict["a"] = ("larry" as! AnyObject) 
dict["b"] = ("moe" as! AnyObject) 
dict["c"] = ("curly" as! AnyObject) 
dict["d"] = (4 as! AnyObject) 

myArray.append(dict as! AnyObject) 

Ohne anhängt, können Sie es wie folgt tun:

var myArray: [AnyObject] = [ ([ 
    "a" : ("hickory" as! AnyObject), 
    "b" : ("dickory" as! AnyObject), 
    "c" : ("dock" as! AnyObject), 
    "d" : (6 as! AnyObject) 
    ] as! AnyObject), ([ 
    "a" : ("three" as! AnyObject), 
    "b" : ("blind" as! AnyObject), 
    "c" : ("mice" as! AnyObject), 
    "d" : (5 as! AnyObject) 
    ] as! AnyObject), ([ 
    "a" : ("larry" as! AnyObject), 
    "b" : ("moe" as! AnyObject), 
    "c" : ("curly" as! AnyObject), 
    "d" : (4 as! AnyObject) 
    ] as! AnyObject) 
] 

dem Sie das gibt gleiches Ergebnis. Obwohl, wenn nur der Wert Objekt im Wörterbuch ändern muss, nicht wahr, die Elemente des Arrays werfen müssen:

var myArray: [Dictionary<String, AnyObject>] = [[ 
    "a" : ("hickory" as! AnyObject), 
    "b" : ("dickory" as! AnyObject), 
    "c" : ("dock" as! AnyObject), 
    "d" : (6 as! AnyObject) 
    ], [ 
    "a" : ("three" as! AnyObject), 
    "b" : ("blind" as! AnyObject), 
    "c" : ("mice" as! AnyObject), 
    "d" : (5 as! AnyObject) 
    ], [ 
    "a" : ("larry" as! AnyObject), 
    "b" : ("moe" as! AnyObject), 
    "c" : ("curly" as! AnyObject), 
    "d" : (4 as! AnyObject) 
    ] 
] 

Dann zu sortieren, verwenden Sie die sort() Verschluss, der ein sortiert Array an Ort und Stelle. Die von Ihnen angegebene Closure benötigt zwei Argumente ($ 0 und $ 1) und gibt ein Bool zurück. Die Schließung sollte wahr zurückgeben, wenn $ 0 vor $ 1 bestellt wird, oder falsch, wenn es danach kommt. Um dies zu tun, haben Sie eine Menge werfen:

//myArray starts as: [ 
// ["d": 6, "b": "dickory", "c": "dock", "a": "hickory"], 
// ["d": 5, "b": "blind", "c": "mice", "a": "three"], 
// ["d": 4, "b": "moe", "c": "curly", "a": "larry"] 
//] 

myArray.sort{ 
    (($0 as! Dictionary<String, AnyObject>)["d"] as? Int) < (($1 as! Dictionary<String, AnyObject>)["d"] as? Int) 
} 

//myArray is now: [ 
// ["d": 4, "b": "moe", "c": "curly", "a": "larry"], 
// ["d": 5, "b": "blind", "c": "mice", "a": "three"], 
// ["d": 6, "b": "dickory", "c": "dock", "a": "hickory"] 
//] 
+0

Nein, das hat nicht funktioniert. Es ergab sich ein Fehler: Kann keine Überladung für 'sortierte' finden, die eine Argumentliste vom Typ akzeptiert '(Array , (_, _) -> _)' Können Sie dies in XCode versuchen, um zu sehen, ob Ihre Idee funktioniert? Update: Warten Sie, ich habe versucht, den gesamten von Ihnen bereitgestellten Code-Block zu verwenden, der auch eine aktualisierte Array-Deklaration enthält. Der Fehler ist verschwunden, aber die Art hat nicht funktioniert. Ich habe: [b: dickory, a: Hickory, c: docken] [b: blind, a: drei, c: Mäuse] [b: moe, a: larry, c: lockig] –

+0

Yeah du hast um die Deklarationen wie oben beschrieben zu ändern. 'var myArray = Array >() var dict = Wörterbuch () ' – oisdk

+0

Bitte lesen Sie die vorherige Antwort, die ich aktualisiert habe. Der Fehler ist verschwunden, aber die Art hat nicht funktioniert. Ich habe Ihren Code direkt in XCode zusammen mit println (myArray [0]) eingefügt println (myArray [1]) println (meinArray [2]) und haben: [b: dickory, a: hickory, c: dock] [b : blind, a: drei, c: mäuse] [b: moe, a: larry, c: lockig] –

3

Ich glaube, du bist für SortDescriptor in Objective C suchen, es ist viel einfacher, in schnellen, da die Array-Typ eine Methode hat sorted diesen Code versuchen es funktioniert für mich:

var myArray = Array<Dictionary<String, String>>() 
var dict = Dictionary<String, String>() 

dict["a"] = "hickory" 
dict["b"] = "dickory" 
dict["c"] = "dock" 

myArray.append(dict) 

dict["a"] = "three" 
dict["b"] = "blind" 
dict["c"] = "mice" 

myArray.append(dict) 

dict["a"] = "larry" 
dict["b"] = "moe" 
dict["c"] = "curly" 

myArray.append(dict) 

println(myArray[0]) 
println(myArray[1]) 
println(myArray[2]) 

var sortedResults = myArray.sorted { 
    (dictOne, dictTwo) -> Bool in 
    return dictOne["c"]! < dictTwo["c"]! 
}; 
println(sortedResults); 

EDIT

ich den Wörterbuchtyp geändert, weil ich sah, dass Sie nur Strings verwendet haben. In einem allgemeinen Fall mit AnyObject müssen Sie nur vor dem Vergleich casten:

Viel Glück.

+0

Danke! Ich habe es ausprobiert, aber ich sehe, dass Sie die Deklaration von AnyType in String geändert haben. Das reale Weltprogramm, das diesem Beispiel entspricht, erfordert, dass es AnyType bleibt. Tatsächlich ist das bestimmte Wörterbuchelement, nach dem ich sortiere, ein Int. Haben sie eine Idee? –

+0

Sie müssen nicht zwingen, Ihre Wörterbuchwerte für den Vergleich auszupacken. 'dictOne [" c "] oisdk

3
var myArray: [AnyObject] = [] 
var dict:[String: AnyObject] = [:] 

dict["a"] = "hickory" 
dict["b"] = "dickory" 
dict["c"] = "dock" 
dict["d"] = 5 

myArray.append(dict) 

dict["a"] = "three" 
dict["b"] = "blind" 
dict["c"] = "mice" 
dict["d"] = 6 

myArray.append(dict) 

dict["a"] = "larry" 
dict["b"] = "moe" 
dict["c"] = "curly" 
dict["d"] = 2 

myArray.append(dict) 

let myArraySorted = myArray.sorted{$1["d"] as? Int > $0["d"] as? Int} as! [[String: AnyObject]] 

println(myArraySorted) // [[b: moe, a: larry, d: 2, c: curly], [b: dickory, a: hickory, d: 5, c: dock], [b: blind, a: three, d: 6, c: mice]]" 

oder

var myArray: [[String:AnyObject]] = [] 
var dict:[String: AnyObject] = [:] 

dict["a"] = "hickory" 
dict["b"] = "dickory" 
dict["c"] = "dock" 
dict["d"] = 5 

myArray.append(dict) 

dict["a"] = "three" 
dict["b"] = "blind" 
dict["c"] = "mice" 
dict["d"] = 6 

myArray.append(dict) 

dict["a"] = "larry" 
dict["b"] = "moe" 
dict["c"] = "curly" 
dict["d"] = 2 

myArray.append(dict) 

let myArraySorted = myArray.sorted{$1["d"] as? Int > $0["d"] as? Int} 

println(myArraySorted) // "[[b: moe, a: larry, d: 2, c: curly], [b: dickory, a: hickory, d: 5, c: dock], [b: blind, a: three, d: 6, c: mice]]" 
1

, wenn wir die Daten analysieren, dann können wir durch sortieren NSSortDescriptor mit

let dataDict1 = responseDict.valueForKey("Data") 
self.customerArray = dataDict1!.valueForKey("Customers") as! NSMutableArray 

var tempArray = NSMutableArray() 
for index in self.customerArray { 
    tempArray.addObject(index.valueForKey("Customer") as! NSMutableDictionary) 
} 

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "name", ascending: true, selector: "caseInsensitiveCompare:") 
let sortedResults: NSArray = tempArray.sortedArrayUsingDescriptors([descriptor]) 
self.customerArray = NSMutableArray(array: sortedResults) 
Verwandte Themen