2016-09-15 3 views
3

Ich habe eine .plist-Datei mit Root-Wörterbuch und Ladeschlüssel von Buchstaben wie:Sortierung Array Werte in Dictionary of Swift 3

["A": ["AXB", "ACD", "ABC"], ... ] 

Es wird von richtig wäre: Dann

["A": ["ABC", "ACD", "AXB"], ... ] 

I möchte die Array-Itens des A-Indexes sortieren. Also versuchte ich tun also:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 

var musicalGroups : NSDictionary = NSDictionary() 
var keysOfMusicalGroups : NSMutableArray = NSMutableArray() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let bundle = Bundle.main 
    let path = bundle.path(forResource: "bandas", ofType: "plist") 
    musicalGroups = NSDictionary(contentsOfFile: path!)! 
    keysOfMusicalGroups = NSMutableArray(array: musicalGroups.allKeys) 
    keysOfMusicalGroups.sort(using: NSSelectorFromString("compare:")) 

} 

Und ich habe gerade die Schlüssel Wörterbuch keysOfMusicalGroups.sort Code sortiert mit

enter image description here

Jede Hilfe geschätzt wird. Danke im Voraus!

+2

Ihr Code sortiert nur die Schlüssel. Sie müssen jedes einzelne Array im Hauptwörterbuch sortieren. – rmaddy

+0

Warum verwenden Sie 'NSArray',' NSDictionary' usw. anstelle ihrer Swift-Gegenstücke? – NRitH

+0

@NRitH Ja, es ist so, als ob ich gelernt habe, mit TableView zu arbeiten. Ich habe diese Methoden implementiert. – Gaspar

Antwort

5

Sie müssen nur Ihre Dictionary-Schlüssel sortieren und die einzelnen Werte (Array) zu dem resultierenden Array 2D sortiert anhängen:

let dict = ["A": ["Angra", "Aerosmith", "ACDC", "Avantasia"],"B": ["Barao Vermelho", "Bon Jovi", "Bee Gees"],"C": ["Cachorro Loco", "Coldplay", "Creed"] ] 

let sortedArray2D = dict.sorted{ $0.key < $1.key }.map { $0.value.sorted() } 

print(sortedArray2D) // "[["ACDC", "Aerosmith", "Angra", "Avantasia"], ["Barao Vermelho", "Bee Gees", "Bon Jovi"], ["Cachorro Loco", "Coldplay", "Creed"]]\n" 

Ihre letzte Tabellenansicht sollte wie folgt aussehen:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
    var musicalGroups: [[String]] = [] 
    var musicalTitles: [String] = [] 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     let dict = NSDictionary(contentsOfFile: Bundle.main.path(forResource: "bandas", ofType: "plist")!) as? [String: [String]] ?? [:] 
     musicalTitles = dict.keys.sorted() 
     musicalGroups = dict.sorted{ $0.key < $1.key }.map { $0.value.sorted() } 
    } 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return musicalGroups[section].count 
    } 
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
     return musicalTitles[section] 
    } 
    func numberOfSections(in tableView: UITableView) -> Int { 
     return musicalTitles.count 
    } 
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = UITableViewCell(style: .default, reuseIdentifier: "exemplo") 
     cell.textLabel?.text = musicalGroups[indexPath.section][indexPath.row] 
     return cell 
    } 
} 
+1

Es funktioniert perfekt! Ich danke dir sehr. – Gaspar

+0

Gern geschehen –

-1

A mehr leistungsmäßig Antwort, basierend auf @ Leo-Dabus ‚s, ist:

let dict = ["A": ["Angra", "Aerosmith", "ACDC", "Avantasia"],"B": ["Barao Vermelho", "Bon Jovi", "Bee Gees"],"C": ["Cachorro Loco", "Coldplay", "Creed"] ] 

let sortedArray2D: [[String]] = dict.keys.sorted().map{ dict[$0]!.sorted() } 

print(sortedArray2D) // "[["ACDC", "Aerosmith", "Angra", "Avantasia"], ["Barao Vermelho", "Bee Gees", "Bon Jovi"], ["Cachorro Loco", "Coldplay", "Creed"]]\n" 

Dies funktioniert besser, weil der Compiler jetzt weiß, dass sortedArray2D die gleiche Größe wie dict hat.

Auch so ist sortedArray2D eine Konstante (let), und kein var mehr (ermöglicht noch weitere Leistungsverbesserungen).

+1

Woher weiß der Compiler, dass 'map' ein Array gleicher Größe zurückgibt? Ist irgendwo dokumentiert, dass der Swift-Compiler spezielle Optimierungen um 'map' hat? –

+0

Von https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html. Kurz gesagt: Die '' map'' Methode verwendet eine Schließung als einziges Argument. Die Schließung wird einmal für jedes Element in dem Array aufgerufen und gibt einen alternativen abgebildeten Wert (möglicherweise eines anderen Typs) für dieses Element zurück. Zusammenfassend: Mit '' map'' geben wir dem Compiler mehr Informationen darüber, was das neue Array sein soll. Erlaubt es, die richtige Speichergröße zuzuordnen (und wahrscheinlich auch etwas anderes, das mir nicht bekannt ist). –

+1

Das Problem ist, dass 'map' intern wahrscheinlich eine' var' verwendet und 'append' aufruft, um das neue Array zu erstellen, also obwohl es wie eine Optimierung aussieht, ist es genau das gleiche Verfahren in einer Funktion, außer mit dem Overhead eines Methodenaufrufs und wiederholte Abschlussaufrufe. Man könnte also argumentieren, dass es tatsächlich weniger leistungsfähig ist. –