前言:謂詞在集合過濾以及CoreData中有著廣泛的應用。本文以Playground上的Swift代碼為例,講解如何使用NSPredicate。
先在Playground上建立一個數組,為後文的謂詞過濾做准備.這裡我們充血了Description屬性來為提供更加明顯的輸出。
import UIKit
class Person:NSObject {
var name:String
var age:Int
init(name:String,age:Int) {
self.name = name
self.age = age
super.init()
}
override var description:String{
return name:(self.name) age:(self.age)
}
}
let persons = NSMutableArray()
persons.addObject(Person(name: Jack Tomphon, age: 23))
persons.addObject(Person(name: Mikle Steven, age: 25))
persons.addObject(Person(name: Tacmk, age: 24))
let pridicateByAge = NSPredicate(format: age == 24)
let pridicateByAge2 = NSPredicate(format: age == %@,NSNumber(int: 24))
let pridicateByAge3 = NSPredicate(format: %K == %@,age,NSNumber(int: 24))
let pridicateByAge4 = NSPredicate (format: age == $age)
let result = persons.filteredArrayUsingPredicate(pridicateByAge)
let resule2 = persons.filteredArrayUsingPredicate(pridicateByAge2)
let result3 = persons.filteredArrayUsingPredicate(pridicateByAge3)
let result4 = persons.filteredArrayUsingPredicate(pridicateByAge4.predicateWithSubstitutionVariables([age:NSNumber(int: 24)]))
然後,再看看Playgound給出的動態結果
可以看到,以上四種方式的效果是一樣的,由此我們接著講解謂詞的語法結構。
%@
對應數字,字符串,日期的替代值 使用%K
對應要比較的屬性,也就是KVC中的key 使用$變量名
來表示通配的變量,然後predicateWithSubstitutionVariables
來決定具體的變量值
比較符號,都是針對於左邊表達式和右邊表達式
1. > 大於
2. > =大於等於
3. < 小於
4. <=小於等於
5. ==等於
6. != 或者<> 不等於
7. BETWEEN 介於兩者之間,包括上下限
舉個例子
let pridivateByAge5 = NSPredicate(format: age BETWEEN { %@ , %@ }, NSNumber(int: 24),NSNumber(int: 25))
let result5 = persons.filteredArrayUsingPredicate(pridivateByAge5)
就是過濾24 <=age<=25
所以,可以看到Playground給出的結果是
[name:Mikle Steven age:25, name:Tacmk age:24]
較為簡單,這裡不舉例子了
匹配以Ja開頭
let pridivateByName1 = NSPredicate(format: name BEGINSWITH %@,Ja)
let result6 = persons.filteredArrayUsingPredicate(pridivateByName1)
println(result6)
名字裡包含ac,不區分大小寫,並且年齡大於等於24
let pridivateByName2 = NSPredicate(format: name CONTAINS %@ && age >= %@, ac,NSNumber(int: 24))
let result7 = persons.filteredArrayUsingPredicate(pridivateByName2)
println(result7)
復合正則表達式T[a-z]*k
let privatedivateByName3 = NSPredicate(format: name MATCHES 'T[a-z]*k')
let result8 = persons.filteredArrayUsingPredicate(privatedivateByName3)
名字是兩者中的一個
let privatedivateByName4 = NSPredicate(format: name IN {'Tacmk','Jack Tomphon'})
let result9 = persons.filteredArrayUsingPredicate(privatedivateByName4)
注意:基於Blcok的謂詞不能用在CoreData的數據過濾上。基於Block能夠靈活的定制謂詞。
簡單的Block定義age >24
let blockPredicate = NSPredicate { (person: AnyObject!, [NSObject : AnyObject]!) -> Bool in
var result = false
if let castResult = person as? Person{
if castResult.age > 24{
result = true
}
}
return result
}
let result10 = persons.filteredArrayUsingPredicate(blockPredicate)