在字典中过滤数组 - Swift
Filtering an Array inside a Dictionary - Swift
我正在尝试根据客户的姓氏在索引词典中搜索 return 特定客户。以下是我正在使用的数据结构。每个客户端对象都有一个名称 属性,它是一个字符串。
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!
当我建立索引时,联系人字典 returns:
{A: [Client("Andrew")]}
字母数组returns:
[A]
我正在使用 UISearchController 来显示过滤后的客户端数组。
func updateSearchResults(for searchController: UISearchController) {
// how to filter the dictionary
self.tableView.reloadData()
}
但是,我不知道如何过滤字典以 return 正确的客户列表。我试过使用
contacts.filter(isIncluded: ((key: String, value: [Client])) throws -> Bool((key: String, value: [Client])) throws -> Bool)
但是我对实现很困惑。我正在使用 Xcode 8.0 和 Swift 3.0。
如果有人能指出正确的方向,我将不胜感激。如果我需要澄清任何事情,请告诉我。先感谢您。完整代码可以在我的 Github
找到
主要问题是您使用字典作为数据源数组。
我的建议是使用自定义结构作为模型
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)
}
}
然后创建数据源数组
var contacts = [Contact]()
和计算出的字母数组属性
var letters : [String] = {
return contacts.map{ [=12=].letter }
}
按字母排序数组很容易
contacts.sort{ [=13=].letter < .letter }
现在可以这样搜索/过滤了(text
是要搜索的文字)
filteredClient.removeAll()
for contact in contacts {
let filteredContent = contact.clients.filter {[=14=].name.range(of: text, options: [.anchored, .caseInsensitive, .diacriticInsensitive]) != nil }
if !filteredContent.isEmpty {
filteredClient.append(filteredContent)
}
}
如果您将 filteredClient
也声明为 [Contact]
并使用过滤的项目创建临时 Contact
实例,您甚至可以保留部分(字母)。
当然,您需要更改所有 table 视图数据源/委托方法以符合 Contact
数组,但这是值得的。作为数据源的数组比字典更有效。
我正在尝试根据客户的姓氏在索引词典中搜索 return 特定客户。以下是我正在使用的数据结构。每个客户端对象都有一个名称 属性,它是一个字符串。
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!
当我建立索引时,联系人字典 returns:
{A: [Client("Andrew")]}
字母数组returns:
[A]
我正在使用 UISearchController 来显示过滤后的客户端数组。
func updateSearchResults(for searchController: UISearchController) {
// how to filter the dictionary
self.tableView.reloadData()
}
但是,我不知道如何过滤字典以 return 正确的客户列表。我试过使用
contacts.filter(isIncluded: ((key: String, value: [Client])) throws -> Bool((key: String, value: [Client])) throws -> Bool)
但是我对实现很困惑。我正在使用 Xcode 8.0 和 Swift 3.0。
如果有人能指出正确的方向,我将不胜感激。如果我需要澄清任何事情,请告诉我。先感谢您。完整代码可以在我的 Github
找到主要问题是您使用字典作为数据源数组。
我的建议是使用自定义结构作为模型
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)
}
}
然后创建数据源数组
var contacts = [Contact]()
和计算出的字母数组属性
var letters : [String] = {
return contacts.map{ [=12=].letter }
}
按字母排序数组很容易
contacts.sort{ [=13=].letter < .letter }
现在可以这样搜索/过滤了(text
是要搜索的文字)
filteredClient.removeAll()
for contact in contacts {
let filteredContent = contact.clients.filter {[=14=].name.range(of: text, options: [.anchored, .caseInsensitive, .diacriticInsensitive]) != nil }
if !filteredContent.isEmpty {
filteredClient.append(filteredContent)
}
}
如果您将 filteredClient
也声明为 [Contact]
并使用过滤的项目创建临时 Contact
实例,您甚至可以保留部分(字母)。
当然,您需要更改所有 table 视图数据源/委托方法以符合 Contact
数组,但这是值得的。作为数据源的数组比字典更有效。