我有以下数据:
NAME | LAST_NAME | PLACE
Roger - Martins - Miami
Mary - Rogers - Paris
Jack - Smith - Maryland
Alfred - Cooper - Germany
... and many more
我有一个这样的谓词:
let searchPredicateName = NSPredicate(format: Database.Key.Name + " CONTAINS[cd] %@", _searchString)
let searchPredicateLastName = NSPredicate(format: Database.Key.LastName + " CONTAINS[cd] %@", _searchString)
let searchPredicatePlace = NSPredicate(format: Database.Key.Place + " CONTAINS[cd] %@", _searchString)
let finalPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [searchPredicateTitle, searchPredicateLastName, searchPredicatePlace])
当我搜索例如" Mar"那么我得到的结果将是:
Roger - Martins - Miami
Mary - Rogers - Paris
Jack - Smith - Maryland
结果还可以,但我想先让Mary Rogers。一种选择是单独获取,但我不会有一个NSFetchedResultsController作为数据源,这会影响性能
答案 0 :(得分:1)
我认为您实际上要寻找的是 NSSortDescriptor
。
当您使用 NSFetchedResultsController
时,您的 NSFetchRequest
必须有一个排序描述符 - 这就是您进行排序的时间。
NSPredicate
用于比较。即:您要查找的内容。
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "section", ascending: true),// sort by section key first
NSSortDescriptor(key: "Name", ascending: true), //continue sorting by first name
NSSortDescriptor(key: "LastName", ascending: true), //continue sorting by last name.
NSSortDescriptor(key: "Place", ascending: true)] //finally by place.
答案 1 :(得分:1)
在查看了上面 hush-entangle 的评论后,我可以清楚地看到我的答案是完全错误的。我有点太兴奋了,无法开始使用这个网站..您实际上是在搜索字符串位置,可能使用 UISearchController 是吗?在这种情况下,您要对结果进行排序,即:
func sortForString(_ string: String) -> [Person] {
let string = string.lowerCased()
// searchResultsArray or if you want all just sort the fetched objects
(fetchedResultsController.fetchedObjects?.sorted(by: { lhs, rhs in
personInfoString(lhs).range(of: string ).lowerBound < personInfoString(rhs).range(of: string ).lowerBound
})) ?? [Person]()
}
func personInfoString(_ person: Person) -> NSString {
(person.first ?? "").appending(person.last ?? "").appending(person.place ?? "").lowercased() as NSString
}
let sorted = sortForString("Mar")
然后显示您排序的字符串。 请注意,如果不包含搜索字符串,则保留原始顺序。
清理可能是
extension Person {
func sortableString() -> NSString {
(self.first ?? " ").appending(self.last ?? " ").appending(self.place ?? " ").lowercased() as NSString
}
}
extension NSFetchedResultsController where ResultType == Person {
func sortedObjects(for searchString: String) -> [Person] {
(self.fetchedObjects?.sorted(by: { lhs, rhs in
lhs.sortableString().range(of: searchString ).lowerBound < rhs.sortableString().range(of: searchString ).lowerBound
})) ?? [Person]()
}
}
答案 2 :(得分:0)
我假设您有一些实体 UserMO
,其中包含字段 name
、lastName
和 place
。另外,我假设您使用的是 UISearchController
。
要按名称排序,请使用 NSSortDescriptor
。我们省略谓词,因为我们最初想要显示所有元素。基于此,我们将编写一个用于创建控制器的函数:
func createFetchedResultsController() -> NSFetchedResultsController<UserMO> {
let request: NSFetchRequest<UserMO> = UserMO.fetchRequest()
request.sortDescriptors = [
NSSortDescriptor(keyPath: \UserMO.name, ascending: true)
]
return NSFetchedResultsController<UserMO>(
fetchRequest: request,
managedObjectContext: context,
sectionNameKeyPath: nil,
cacheName: nil)
}
在用户编辑搜索字符串的那一刻,委托方法 updateSearchResults
将被调用。在那里,根据用户输入的内容,我们编辑谓词。您无需更改排序规则。
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let text = searchController.searchBar.text ?? ""
let predicate: NSPredicate?
if text.isEmpty {
predicate = nil // We want to display all items
} else {
predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [
NSPredicate(format: Database.Key.Name + " CONTAINS[cd] %@", text),
NSPredicate(format: Database.Key.LastName + " CONTAINS[cd] %@", text),
NSPredicate(format: Database.Key.Place + " CONTAINS[cd] %@", text),
])
}
fetchedResultsController.fetchRequest.predicate = predicate
do {
try fetchedResultsController.performFetch()
} catch {
print(error)
}
}
}