代码之家  ›  专栏  ›  技术社区  ›  Justin Witham

n预测格式问题

  •  0
  • Justin Witham  · 技术社区  · 8 年前

    我正在创建一个iOS应用程序,希望用户能够通过 UITableView 并基于各种不同的输入显示结果。我使用了一个NSPredicate,其中多个条件以“或”分隔,但出于某种原因,它只搜索第一个条件,而没有搜索其他条件。

    let searchPredicate = NSPredicate(format: "(SELF.firstName CONTAINS[c]
    %@) OR (SELF.lastName CONTAINS[c] %@) OR (SELF.major CONTAINS[c] %@) OR
    (SELF.year CONTAINS[c] %@) OR (SELF.gpa CONTAINS[c] %@)",
    searchController.searchBar.text!)
    

    我的参数是名字、姓氏、专业、年份和gpa。当我在搜索栏中输入除了名字以外的任何东西时,都不会显示结果。但输入名字确实会返回匹配项。为什么会这样?我的NSPredicate格式不正确吗?

    4 回复  |  直到 8 年前
        1
  •  2
  •   rmaddy    6 年前

    您有五个 %@ 谓词中的格式说明符,因此需要传递五个值。你只是路过一个。

    你需要重复一遍 searchController.searchBar.text! 五次。顺便说一句,将其分配给一个安全展开的变量,并重复该变量五次。这将减少打字。

    if let srch = searchController.searchBar.text {
        let searchPredicate = NSPredicate(format: "(SELF.firstName CONTAINS[c] %@) OR
            (SELF.lastName CONTAINS[c] %@) OR
            (SELF.major CONTAINS[c] %@) OR
            (SELF.year CONTAINS[c] %@) OR
            (SELF.gpa CONTAINS[c] %@)", srch, srch, srch, srch, srch)
        ...
    }
    
        2
  •  1
  •   Samip Shah    8 年前
    if let text = searchController.searchBar.text, text.characters.count > 0{
        var predicates = [NSPredicate]()
        predicates.append(NSPredicate(format: "self.firstName CONTAINS[c]",text))
        predicates.append(NSPredicate(format: "self.lastName CONTAINS[c]",text))
        predicates.append(NSPredicate(format: "self.major CONTAINS[c]",text))
        predicates.append(NSPredicate(format: "self.year CONTAINS[c]",text))
        predicates.append(NSPredicate(format: "self.gpa CONTAINS[c]",text))
    
        let searchPredicate:NSPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates)
    
        }
    
        3
  •  0
  •   paulvs    8 年前

    未经测试,但如果所有子信用证都相同,这可能是Swift最简单的语法:

    if let text = searchController.searchBar.text {
        let myCompondPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: ["firstName", "lastName", "major", "year", "gpa"].map {
            NSPredicate(format: "%K CONTAINS[c] %@", $0, text)
        })
    
        // Do something with myCompondPredicate here..
    }
    
        4
  •  0
  •   Alexander    8 年前

    对于这样一个简单的静态谓词,我会选择本机Swift方法:

    import Foundation
    
    struct Student {
        let firstName: String
        let lastName: String
        let major: String
        let gpa: Double
    }
    
    extension Student {
        func anyFields(contain searchString: String) -> Bool {
            return firstName.contains(searchString)
                || lastName.contains(searchString)
                || major.contains(searchString)
                || String(gpa).contains(searchString)
        }
    
        // Alternate implementation:
        /* 
        func anyFields(contain searchString: String) -> Bool {
            return [firstName, lastName, major, String(gpa)].contains(where: { field in
                field.contains(searchString)
            })
        } */
    }
    
    
    let matchingStudents = students.filter(Student.anyFields(contain:))