无法过滤对象数组

时间:2019-08-26 09:55:37

标签: swift nspredicate

我试图通过其属性之一过滤对象数组。尝试了很多解决方案,但是在我开始输入后却抛出错误

//我的模型班

class Book{

var bookId:Int?

var bookName:String?

//omitted init function

}

// viewController //这是我的文本字段委托方法

let myArray:[Book] = [Book(bookId:23,bookName:"book1"),Book(bookId:53,bookName:"book2"),Book(bookId:43,bookName:"book3"),] 

func textField(_ textField: UITextField, shouldChangeCharactersIn 

range: NSRange, replacementString string: String) -> Bool 
{

       lastCharactar = string

        textFieldText = myTextField.text! + lastCharactar

        let predicate = NSPredicate(format: "ANY SELF.bookName BEGINSWITH %@", textFieldText)

        let arr = ( myArray as NSArray).filtered(using: predicate)

        return true
    }

I am getting the following error
"this class is not key value coding-compliant for the key bookName."

3 个答案:

答案 0 :(得分:1)

Swift Array不需要谓词即可过滤其内容。 Swift数组具有用于过滤数组的filter方法。例如:

struct Book{
    var bookId:Int?
    var bookName:String?
}

let myArray:[Book] = [Book(bookId:23,bookName:"book1"),Book(bookId:53,bookName:"book2"),Book(bookId:43,bookName:"book3"),]

func textField(_ textField: UITextField, shouldChangeCharactersIn 
range: NSRange, replacementString string: String) -> Bool 
{
    lastCharactar = string
    textFieldText = myTextField.text! + lastCharactar

    let arr = myArray.filter { (book) -> Bool in
      if let name = book.bookName, name.hasPrefix(textFieldText) {
        return true
      }
      return false
    }

   return true
 }

注意:struct是一种值类型,将其值分配给变量或常量时或将其传递给函数时将其值复制,而class是引用类型,其值默认情况下不会被复制。

答案 1 :(得分:0)

转换为NSArray来应用谓词的桥要求通过添加@objc属性来实现属性的键值兼容,并且该类甚至必须是NSObject的子类。

但是这是Swift,不需要使用NSPredicateNSArray。这种本机语法具有相同的作用

let arr = myArray.filter{ $0.bookName.range(of: textFieldText, options: .anchored) != nil }

旁注:

显然,所有书籍都具有nameid,因此将对象声明为具有非可选常量成员的struct并删除多余的命名。初始化程序是免费的。

struct Book {
    let id : Int 
    let name : String
}

答案 2 :(得分:-1)

 var myArray = [Book(bookName:"book1", bookId:23),Book(bookName:"book2", bookId:53),Book(bookName:"book3", bookId:43)]

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

            var lastCharactar = string
            var textFieldText = myTextField.text! + lastCharactar

            let arr = myArray.filter{ $0.bookName!.range(of: textFieldText, options: .caseInsensitive) != nil }
            print(arr)

            return true

        }

 struct Book {
        var bookName : String?
        var bookId : Int?
    }