字符串数组中不区分大小写的过滤器可搜索文本
Case incensitive filter searchable text in an array of strings
我在一个结构中有一个字符串数组。这会填充一个列表,我使用 .searchable 来过滤那里的元素。我可以在每个项目中按文本、日期或标签过滤它们。全部完成,不考虑大小写。
现在,对于标签,我正在努力寻找过滤它们的正确方法:
let dateFormatter = DateFormatter()
struct LibItem: Codable, Hashable, Identifiable {
let id: UUID
var text: String
var date = Date()
var dateText: String {
dateFormatter.dateFormat = "EEEE, MMM d yyyy, h:mm a"
return dateFormatter.string(from: date)
}
var tags: [String] = []
}
final class DataModel: ObservableObject {
@AppStorage("myapp") public var collectables: [LibItem] = []
init() {
self.collectables = self.collectables.sorted(by: {
[=10=].date.compare(.date) == .orderedDescending
})
}
func sortList() {
self.collectables = self.collectables.sorted(by: {
[=10=].date.compare(.date) == .orderedDescending
})
}
}
struct ContentView: View {
@EnvironmentObject private var data: DataModel
@State var searchText: String = ""
var body: some View {
NavigationView {
List(filteredItems) { collectable in
VStack(alignment: .leading) {
Spacer()
Text(collectable.text).font(.body).padding(.leading).padding(.bottom, 1)
Spacer()
}
}
.listStyle(.plain)
.searchable(
text: $searchText,
placement: .navigationBarDrawer(displayMode: .always),
prompt: "Search..."
)
}
}
var filteredItems: [LibItem] {
switch selectedItem {
case 1: // date
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].dateText.localizedCaseInsensitiveContains(searchText)
}
case 2: //tags <--- here how do I search and filter by, case insensitive?
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].tags.contains(searchText)
}
default:
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].text.localizedCaseInsensitiveContains(searchText)
}
}
}
}
通过暂时将比较的两边都转为小写来比较两个小写的字符串。
您可以在代码中使用的示例:
[=10=].tags.compactMap { [=10=].lowercased() }.contains(searchText.lowercased())
如果需要检查tags
的每一项是否包含字符串的部分,需要迭代:
var isTagFound = false
[=11=].tags.compactMap { [=11=].lowercased() }.forEach {
if [=11=].contains(searchText.lowercased()) {
isTagFound = true
}
}
对于严格相等,不区分大小写:
return data.collectables.filter {
searchText.isEmpty
? true
: [=10=].tags.contains { tag in tag.caseInsensitiveCompare(searchText) == .orderedSame }
}
对于子字符串,可以使用range(of:)
方法:
return data.collectables.filter {
searchText.isEmpty
? true
: [=11=].tags.contains { tag in tag.range(of: searchText, options: .caseInsensitive) != nil }
}
或者,使用您之前已经使用过的localizedCaseInsensitiveContains
:
return data.collectables.filter {
searchText.isEmpty
? true
: [=12=].tags.contains { tag in tag.localizedCaseInsensitiveContains(searchText) }
}
我在一个结构中有一个字符串数组。这会填充一个列表,我使用 .searchable 来过滤那里的元素。我可以在每个项目中按文本、日期或标签过滤它们。全部完成,不考虑大小写。
现在,对于标签,我正在努力寻找过滤它们的正确方法:
let dateFormatter = DateFormatter()
struct LibItem: Codable, Hashable, Identifiable {
let id: UUID
var text: String
var date = Date()
var dateText: String {
dateFormatter.dateFormat = "EEEE, MMM d yyyy, h:mm a"
return dateFormatter.string(from: date)
}
var tags: [String] = []
}
final class DataModel: ObservableObject {
@AppStorage("myapp") public var collectables: [LibItem] = []
init() {
self.collectables = self.collectables.sorted(by: {
[=10=].date.compare(.date) == .orderedDescending
})
}
func sortList() {
self.collectables = self.collectables.sorted(by: {
[=10=].date.compare(.date) == .orderedDescending
})
}
}
struct ContentView: View {
@EnvironmentObject private var data: DataModel
@State var searchText: String = ""
var body: some View {
NavigationView {
List(filteredItems) { collectable in
VStack(alignment: .leading) {
Spacer()
Text(collectable.text).font(.body).padding(.leading).padding(.bottom, 1)
Spacer()
}
}
.listStyle(.plain)
.searchable(
text: $searchText,
placement: .navigationBarDrawer(displayMode: .always),
prompt: "Search..."
)
}
}
var filteredItems: [LibItem] {
switch selectedItem {
case 1: // date
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].dateText.localizedCaseInsensitiveContains(searchText)
}
case 2: //tags <--- here how do I search and filter by, case insensitive?
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].tags.contains(searchText)
}
default:
return data.collectables.filter {
searchText.isEmpty ? true : [=10=].text.localizedCaseInsensitiveContains(searchText)
}
}
}
}
通过暂时将比较的两边都转为小写来比较两个小写的字符串。
您可以在代码中使用的示例:
[=10=].tags.compactMap { [=10=].lowercased() }.contains(searchText.lowercased())
如果需要检查tags
的每一项是否包含字符串的部分,需要迭代:
var isTagFound = false
[=11=].tags.compactMap { [=11=].lowercased() }.forEach {
if [=11=].contains(searchText.lowercased()) {
isTagFound = true
}
}
对于严格相等,不区分大小写:
return data.collectables.filter {
searchText.isEmpty
? true
: [=10=].tags.contains { tag in tag.caseInsensitiveCompare(searchText) == .orderedSame }
}
对于子字符串,可以使用range(of:)
方法:
return data.collectables.filter {
searchText.isEmpty
? true
: [=11=].tags.contains { tag in tag.range(of: searchText, options: .caseInsensitive) != nil }
}
或者,使用您之前已经使用过的localizedCaseInsensitiveContains
:
return data.collectables.filter {
searchText.isEmpty
? true
: [=12=].tags.contains { tag in tag.localizedCaseInsensitiveContains(searchText) }
}