如何使用 NSPredicate 在对象中搜索?
How to search in an Object with NSPredicate?
在 Nsarray 中,我需要过滤所有包含 searchKey(例如 39013)的元素。目前,它返回错误的值。我的搜索功能有什么问题?我认为问题出在 FORMAT 行,但不知道该怎么办?
要求: Searchbar 必须搜索 LocationModel 对象中声明的 DesenNo 中的值。
这是对象
import UIKit
class LocationModel: NSObject {
//properties
var DesenNo: String?
var Dolar: String?
var Zemin: String?
var En: String?
var Euro: String?
var Renk: String?
}
这是我的搜索功能:
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
filteredData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "LocationModel.DesenNo CONTAINS[c] %@", searchController.searchBar.text!)
let array = self.feedItems.filter { searchPredicate.evaluate(with: ([=11=] as! LocationModel).DesenNo) }
let filterArray = array.map {([=11=] as! LocationModel).DesenNo}
filteredData = filterArray as! [String]
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
您不需要谓词。只需使用一个简单的 Swift 数组过滤器:
假设self.feedItems
声明为[LocationModel]
,你只需要:
let matchingModels = self.feedItems.filter { [=10=].DesenNo?.contains(searchController.searchBar.text!) }
如果您希望将这些结果缩减为仅包含相应 DesenNo
值的列表,请执行:
filteredData = matchingModels.map { [=11=].DesenNo }
附带说明一下,您的 LocationModel
class 不需要扩展 NSObject
。它也应该是 struct
,而不是 class
。
另请注意,标准做法是变量和方法名称以小写字母开头。 Class 和结构名称以大写开头。
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
let matchingModels = self.feedItems.filter { [=12=].DesenNo?.contains(searchController.searchBar.text!) }
filteredData = matchingModels.map { [=12=].DesenNo }
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
如果您出于某种原因真的想使用 NSPredicate
,您可以将代码更新为:
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
let searchPredicate = NSPredicate(format: "DesenNo CONTAINS[c] %@", searchController.searchBar.text!)
let array = self.feedItems.filter { searchPredicate.evaluate(with: [=13=]) }
filteredData = array.map { [=13=].DesenNo }
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
如果 self.feedItems
实际上是 NSArray
而不是适当的 Swift 数组,请更改:
... = self.feedItems.filter { ...
至:
... = (self.feedItems as! [LocationModel]).filter { ...
在 Nsarray 中,我需要过滤所有包含 searchKey(例如 39013)的元素。目前,它返回错误的值。我的搜索功能有什么问题?我认为问题出在 FORMAT 行,但不知道该怎么办?
要求: Searchbar 必须搜索 LocationModel 对象中声明的 DesenNo 中的值。
这是对象
import UIKit
class LocationModel: NSObject {
//properties
var DesenNo: String?
var Dolar: String?
var Zemin: String?
var En: String?
var Euro: String?
var Renk: String?
}
这是我的搜索功能:
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
filteredData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "LocationModel.DesenNo CONTAINS[c] %@", searchController.searchBar.text!)
let array = self.feedItems.filter { searchPredicate.evaluate(with: ([=11=] as! LocationModel).DesenNo) }
let filterArray = array.map {([=11=] as! LocationModel).DesenNo}
filteredData = filterArray as! [String]
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
您不需要谓词。只需使用一个简单的 Swift 数组过滤器:
假设self.feedItems
声明为[LocationModel]
,你只需要:
let matchingModels = self.feedItems.filter { [=10=].DesenNo?.contains(searchController.searchBar.text!) }
如果您希望将这些结果缩减为仅包含相应 DesenNo
值的列表,请执行:
filteredData = matchingModels.map { [=11=].DesenNo }
附带说明一下,您的 LocationModel
class 不需要扩展 NSObject
。它也应该是 struct
,而不是 class
。
另请注意,标准做法是变量和方法名称以小写字母开头。 Class 和结构名称以大写开头。
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
let matchingModels = self.feedItems.filter { [=12=].DesenNo?.contains(searchController.searchBar.text!) }
filteredData = matchingModels.map { [=12=].DesenNo }
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
如果您出于某种原因真的想使用 NSPredicate
,您可以将代码更新为:
func updateSearchResults(for searchController: UISearchController) {
if searchController.isActive {
let searchPredicate = NSPredicate(format: "DesenNo CONTAINS[c] %@", searchController.searchBar.text!)
let array = self.feedItems.filter { searchPredicate.evaluate(with: [=13=]) }
filteredData = array.map { [=13=].DesenNo }
listTableView.reloadData()
} else {
filteredData.removeAll(keepingCapacity: false)
listTableView.reloadData()
}
}
如果 self.feedItems
实际上是 NSArray
而不是适当的 Swift 数组,请更改:
... = self.feedItems.filter { ...
至:
... = (self.feedItems as! [LocationModel]).filter { ...