使用NSPredicate按属性过滤对象数组

3
我有一个Studio数组,每个Studio都有一个名为studioName的属性。
我需要我的搜索框根据用户输入的studioName来过滤Studio。
这是我的当前代码:
var studios = [Studio]()
var filteredStudios = [Studio]()
var studiosToDisplay = [Studio]()

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = searchController.searchBar.text

    print("SEARCH TEXT: \(searchText)")

    if searchText == nil || searchText!.isEmpty {
        studiosToDisplay = studios
        self.resultTableView.reloadData()
        NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
    } else {
        studiosToDisplay.removeAll()
        let searchPredicate = NSPredicate(format: "studioName CONTAINS[c] %@", searchText!)
        let array = (self.studios as NSArray).filteredArrayUsingPredicate(searchPredicate)
        studiosToDisplay = array as! [Studio]
        self.resultTableView.reloadData()
    }
}

现在它不能很好地工作。它可以过滤,但无论我在搜索框中输入什么,我都得到相同的Studio。

我想我需要让谓词知道每次都要查看数组中的单个对象。但我就是想不出办法。 我尝试在格式中添加“ANY”,但那样会崩溃我的应用程序。


你应该正确标记你的问题,因为看起来你正在使用Swift 2(我建议更新你在APP Store中可以获得的最新Xcode版本)。 - Leo Dabus
顺便说一下:使用 searchText == nil 进行空值检查,然后强制解包 (searchText!) 是非常不好的编程实践。 - Alexander
2个回答

9

这显得过于复杂了。这里没有必要使用 NSPredicate

var studios = [Studio]()
var filteredStudios = [Studio]()
var studiosToDisplay = [Studio]()

func updateSearchResultsForSearchController(searchController: UISearchController) {
    let searchText = searchController.searchBar.text

    print("SEARCH TEXT: \(searchText)")

    if let searchText = searchText, !searchText.isEmpty {
        studiosToDisplay = studios.filter{ $0.studioName.contains(searchText) }
    }
    else {
        studiosToDisplay = studios
        NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) //Calls SearchVC
    }

    self.resultTableView.reloadData()
}

1

感谢 @Alexander .. 这是我最终使用的代码:

func updateSearchResultsForSearchController(searchController: UISearchController) {

    let searchText = searchController.searchBar.text

    if let searchText = searchText {
        if !searchText.isEmpty {
            self.studiosToDisplay = self.studios.filter { $0.studioName!.containsString(searchText) }
            for studio in self.studiosToDisplay {
                print("\(studio.studioName!)")
            }
        }
        else {
            self.studiosToDisplay = self.studios
            NSNotificationCenter.defaultCenter().postNotificationName("showResultsBeforeSearchingNotification", object: nil) // Calls SearchVC
        }
    }

    self.resultTableView.reloadData()

}

我发现,我的以前的代码,使用NSPredicate实际上是功能性的 - 我只是在我的tableview中呈现了错误的数组.. 哎呀.. 但现在它可以工作了,我坚持使用更简单的代码。不知道为什么我没有想到使用$0函数 :) .. 无论如何,谢谢!


您可以使用守卫语句来绑定 searchText,而无需额外的缩进层级。 - Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接