我有一个这样的结构:
struct StructName {
var name: String?
var contents: [Content]?
}
Content
看起来像这样:
struct Content {
var contentName: String?
}
现在,我只是按names
数组中的StructName
搜索
var array = [StructName]()
func searchBar(_ searchBar: UISearchBar, textDidChange searchText:String) {
var filteredArray = array.filter { $0.name?.range(of: searchText, options: [.caseInsensitive]) != nil}
}
如果我想同时在contents
中的name
中搜索StructName
中的元素,该如何处理?
如果我这样构造它:
let contentA = [Content(contentName: "Content_1"), Content(contentName: "Content_2")]
let contentB = [Content(contentName: "Content_1"), Content(contentName: "Content_2")]
array[0] = (StructName(name: "Name_1", contents: contentA))
array[1] = (StructName(name: "Name_2", contents: contentB))
我在searchText中写了“ NC”,它应该返回所有内容,因为在“ Name_1”和“ Name_2”中有一个“ N”,在“ Content_1”和“ Content_2”中有一个“ C”。
filteredArray
的示例:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredArray = array.filter{ elements in
var result = false
elements.contents.forEach{ content in
if (content.contentName.lowercased().contains(searchText.lowercased()) ) {
result = true
}
}
if (content.name?.lowercased().contains(searchText.lowercased()))!{
result = true
}
return result
}
}
请注意,这并不能同时进行搜索。
答案 0 :(得分:1)
如果要过滤和查找StructNames(内容数组项与searchBar文本进行比较),请参见以下代码
struct Content {
var contentValue: String
}
struct StructName{
var name: String?
var contents: [Content]?
}
var array = [ StructName(name: "test1", contents: [ Content(contentValue: "contentValue1"), Content(contentValue: "contentValue2"), Content(contentValue: "searchedText") ]) ]
let searchedText = "searchedText"
let filteredArray = array.filter{ structName in
var result = false
structName.contents?.forEach{ content in
if (content.contentValue.lowercased().contains(searchedText.lowercased()) ) {
result = true
}
}
return result
}
答案 1 :(得分:1)
您对同时一词的用法不够清楚,无法描述您期望的搜索结果类型。
我认为,
如果(且仅当)name
匹配 searchText
或contentName
中的任何contents
匹配 {{ 1}},则searchText
实例出现在StructName
中。
(匹配项的定义类似于您帖子中的filteredArray
。)
然后您可以编写如下内容:
name
如果这不是您想要的,则可能需要更精确地指定搜索条件。
(顺便问一下,var filteredArray = array.filter {
$0.name?.range(of: searchText, options: .caseInsensitive) != nil
|| $0.contents?.contains {content in content.contentName?.range(of: searchText, options: .caseInsensitive) != nil} == true
}
还是name
是可选的吗?)
您似乎想按字符进行基于字符的搜索需要
使用一些修改后的示例:
contents
具有一些调试帮助:
var array = [StructName]()
let contentA = [Content(contentName: "Content_1"), Content(contentName: "Content_2")]
let contentB = [Content(contentName: "Content_3"), Content(contentName: "Content_4")]
array.append(StructName(name: "Name_1", contents: contentA))
array.append(StructName(name: "Name_2", contents: contentB))
您可以这样写:
extension StructName: CustomStringConvertible {
var description: String {
return "\(name ?? ""):\(contents?.map{$0.contentName ?? ""}.joined(separator: ";") ?? "")"
}
}
print(array) //->[Name_1:Content_1;Content_2, Name_2:Content_3;Content_4]
输出示例:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText:String) {
let filteredArray = array.filter {element in
!searchText.lowercased().contains {searchChar in
!(element.name ?? "").lowercased().contains(searchChar)
&& !(element.contents ?? []).contains {content in (content.contentName ?? "").lowercased().contains(searchChar)}
}
}
print(filteredArray)
}
不过,由于您的描述还不够清楚,所以我不确定这是否符合您的期望。