2017-03-27 2 views
2

Ich versuche, ein indiziertes Wörterbuch zu durchsuchen, um einen bestimmten Client basierend auf dem Nachnamen des Clients zurückzugeben. Im Folgenden sind die Datenstrukturen, die ich verwende. Jedes Client-Objekt hat eine name -Eigenschaft, die ein String ist.Ein Array in einem Verzeichnis filtern - Swift

var clients = Client.loadAllClients()  //Returns client array 
var contacts = [String: [Client]]()  //Indexed clients in a dictionary 
var letters: [String] = [] 

var filteredClient = [Client]() 
var shouldShowSearchResults = false 
var searchController : UISearchController! 

Wenn ich meine Indizierung zu tun, die Kontakte Wörterbuch Rückkehr:

{A: [Client("Andrew")]} 

Letters Array zurück:

[A] 

ich die UISearchController bin mit der gefilterten Reihe von Clients angezeigt werden soll.

func updateSearchResults(for searchController: UISearchController) { 
    // how to filter the dictionary 
    self.tableView.reloadData() 
} 

Ich habe aber keine Ahnung, wie das Wörterbuch filtern, um die richtige Liste von Kunden zurück. Ich habe versucht zu verwenden

contacts.filter(isIncluded: ((key: String, value: [Client])) throws -> Bool((key: String, value: [Client])) throws -> Bool) 

Aber ich war sehr verwirrt über die Umsetzung. Ich verwende Xcode 8.0 und Swift 3.0.

Wenn mir jemand in die richtige Richtung zeigen könnte, würde das sehr geschätzt werden. Bitte lassen Sie mich wissen, wenn ich etwas klären muss. Vielen Dank im Voraus. Der vollständige Code kann an meinem Github

Antwort

2

Das Hauptproblem zu finden ist, dass Sie einen Wörterbuch als Datenquelle Array verwenden.

Mein Vorschlag ist, eine benutzerdefinierte Struktur als Modell, um Ihre Daten

struct Contact { 
    let letter : String 
    var clients : [Client] 

    init(letter: String, clients : [Client] = [Client]()) { 
     self.letter = letter 
     self.clients = clients 
    } 

    mutating func add(client : Client) { 
     clients.append(client) 
    } 
} 

Dann erstellen Quellenarray als berechnete Eigenschaft

var contacts = [Contact]() 

und den Brief Array zu verwenden

var letters : [String] = { 
    return contacts.map{ $0.letter } 
} 

es einfach ist, um das Array nach dem Buchstaben

zu sortieren
contacts.sort{ $0.letter < $1.letter } 

Jetzt können Sie diese Art und Weise suchen/Filter (text ist der Text gesucht werden)

filteredClient.removeAll() 
for contact in contacts { 
    let filteredContent = contact.clients.filter {$0.name.range(of: text, options: [.anchored, .caseInsensitive, .diacriticInsensitive]) != nil } 
    if !filteredContent.isEmpty { 
     filteredClient.append(filteredContent) 
    } 
} 

Sie auch die Abschnitte (Buchstaben) halten können, wenn Sie erklären filteredClient auch als [Contact] und Erstellen Sie temporäre Contact Instanzen mit den gefilterten Elementen.

Natürlich müssen Sie alle Tabellenansicht Datenquelle/Delegate Methoden, um die Contact-Array zu entsprechen, aber es ist es wert. Ein Array als Datenquelle ist effizienter als ein Wörterbuch.

Verwandte Themen