我试图通过其属性之一过滤对象数组。尝试了很多解决方案,但是在我开始输入后却抛出错误
//我的模型班
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."
答案 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,不需要使用NSPredicate
和NSArray
。这种本机语法具有相同的作用
let arr = myArray.filter{ $0.bookName.range(of: textFieldText, options: .anchored) != nil }
旁注:
显然,所有书籍都具有name
和id
,因此将对象声明为具有非可选常量成员的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?
}