iOS SDK詳解之NSPredicate(Swift)
前言:謂詞在集合過濾以及CoreData中有著廣泛的應用。本文以Playground上的Swift代碼為例,講解如何使用NSPredicate。
準備工作
先在Playground上建立一個數組,為後文的謂詞過濾做準備.這裡我們充血了Description屬性來為提供更加明顯的輸出。
import UIKitclass 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]
複合比較&& 或者AND 邏輯與 || 或者 OR 邏輯或 !或者NOT 邏輯非
較為簡單,這裡不舉例子了
字串比較BEGINSWITH 左邊運算式以右邊運算式開頭 CONTAINS 左邊運算式包含右邊運算式 ENDSWITH 左邊運算式以右邊運算式結尾 LIKE 左邊運算式和右邊運算式相似(簡單的Regex匹配,?匹配一個字元,*匹配0個或者多個字元) MATCHES 可以實現較為複雜的曾則運算式匹配 用方括弧加cd來不區分大小寫和變音符號 IN 左邊的運算式在右邊的集合裡
匹配以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)
複合RegexT[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)
基於Block的謂詞
注意:基於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)