2015-05-25 26 views
9

Próbuję sortować tablicę Swift, która składa się ze słowników. Poniżej przygotowałem działający przykład. Celem jest posortowanie całej tablicy przez element "d" w słownikach. Przygotowałem ten przykład roboczy, który może być umieszczony w Swift projektu:Sortowanie Swift Array słowników według wartości klucza

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

Wynika to w następujący wyjścia do dziennika:

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

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

Celem jest, aby posortować tablicę przez „d "elementem, tak że powyższy wyjściowy będzie zmieniony na następujące (który jest oparty na porządku numerycznym«d»:«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; 
} 

Istnieje kilka innych pytań, które wydają się podobne , ale kiedy się kręcisz Na ich podstawie staje się jasne, że nie zajmują się tym. Dziękuję za pomoc.

Odpowiedz

15

Aby zadeklarować, jeśli trzeba zachować go jako AnyObject, trzeba wyraźnie obsada:

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) 

Bez dopisywania, można zrobić to tak:

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

co daje ten sam wynik. Chociaż, jeśli tylko przedmiotem wartość w słowniku musi się zmienić, nie trzeba rzucić elementy tablicy:

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

Następnie do sortowania, należy użyć sort() zamknięcie, który sortuje Tablica w miejscu. Zamknięcie, które dostarczasz, przyjmuje dwa argumenty (o wartości 0 USD i 1 USD) i zwraca wartość Bool. Zamknięcie powinno zwrócić wartość true, jeśli $ 1 zostanie zamówione przed $ 1, lub false, jeśli przyjdzie po. Aby to zrobić, musisz rzucać bardzo dużo:

//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

Nie, to nie działa. Wynika z tego błąd: Nie można znaleźć przeciążenia dla "posortowanego", który akceptuje listę argumentów typu "(Array , (_, _) -> _) ' Czy możesz spróbować tego w XCode, aby sprawdzić, czy twój pomysł Prace? Aktualizacja: Czekaj, próbowałem użyć całego bloku kodu, który podałeś, który zawiera również zaktualizowaną deklarację tablicy. Błąd zniknął, ale sortowanie nie zadziałało. Mam: [b: dickory, a: hickory, c: dock] [b: niewidomy, a: trzy, c: myszy] [b: moe, a: larry, c: curly] –

+0

Tak, masz zmienić deklaracje, które mam powyżej. 'var myArray = Array >() var dict = Słownik () ' – oisdk

+0

Przeczytaj poprzednią odpowiedź, którą zaktualizowałem. Błąd zniknął, ale sortowanie nie zadziałało. Wkleiłem twój kod bezpośrednio do XCode wraz z println (myArray [0]) println (myArray [1]) println (myArray [2]) i otrzymałem: [b: dickory, a: hickory, c: dock] [b : blind, a: three, c: mice] [b: moe, a: larry, c: curly] –

3

myślę szukasz sortdescriptor w Objective C, jest dużo łatwiejsze w szybkich, gdyż typ Array ma metodę sorted wypróbować ten kod pracował dla mnie:

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

Zmieniłem typ słownika, ponieważ widziałem, że były tylko za pomocą sznurków. W ogólnym przypadku z AnyObject wystarczy wykonać rzutowanie przed wykonaniem porównania:

var sortedResults = myArray.sorted { 
    (dictOne, dictTwo) -> Bool in 
    let d1 = dictOne["d"]! as Int; 
    let d2 = dictTwo["d"]! as Int; 

    return d1 < d2 

}; 
println(sortedResults); 

Powodzenia.

+0

Dziękujemy! Wypróbowałem to, ale widzę, że zmieniłeś deklarację z AnyType na String. Program świata rzeczywistego, który odpowiada temu przykładowi, wymaga, aby pozostała w trybie AnyType. W rzeczywistości szczególny element słownika, który sortuję według, to Int. Masz pomysł? –

+0

Nie trzeba wymuszać odwijania wartości słownika w celu porównania. '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]]" 

lub

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

kiedy analizować dane możemy rozwiązać za pomocą NSSortDescriptor

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) 
Powiązane problemy