文檔定義
NSPredicate:A definition of logical conditions used to constrain a search either for a fetch or for in-memory filtering.(邏輯條件的定義,用於限制對訪存或內存中過濾的搜索。)
謂詞代表邏輯條件,可用於過濾對象集合。 雖然直接從NSComparisonPredicate,NSCompoundPredicate和NSExpression的實例創建謂詞是很常見的,但是您通常會根據由NSPredicate上的類方法解析的格式字符串來創建謂詞。 謂詞格式字符串的示例包括:
1. 簡單比較,例如成績==“ 7”或“ Shaffiq”這樣的名字
2. 大小寫不敏感的查找,例如名稱contains [cd]“ itroen”
3. 邏輯運算,例如(名字,例如“ Mark”)或(姓氏,例如“ Adderley”)
4. 時間範圍限制,例如{$ YESTERDAY,$ TOMORROW}之間的日期。
5. 關係條件,例如group.name之類的“ work *”
6. 聚合操作,例如@ sum.items.price <1000
有關完整的語法參考,請參閱《謂詞編程指南》。
謂詞的創建
謂詞字符串解析器對空格不敏感,對關鍵字不區分大小寫,並且支持嵌套的括號表達式。 它還支持printf樣式的格式說明符(例如%x和%@)-請參閱格式化字符串對象。 變量用 VARIABLE_NAME)-有關更多詳細信息,請參見使用謂詞模板創建謂詞。
predicateFormat 後面的字符串如何設置可以查看 謂詞格式字符串語法
解析器不執行任何語義類型檢查。 它會盡力而爲地創建合適的表達式,但是(尤其是在替換變量的情況下)可能會生成運行時錯誤。(確保format字符串是正確的,否則會運行時崩潰)
//初始化方法
public convenience init(format predicateFormat: String, _ args: CVarArg...)
例子:
//like[c]是不區分大小寫
let pre = NSPredicate.init(format: "(lastName like[c] %@) AND (birthday > %@)", "abc",NSNumber.init(value: 10))
let result = pre.evaluate(with: ["lastName":"abc","birthday":11])
print(result)// true
出來通過固定字符串創建謂詞以外,還支持 字符串常量,變量和通配符創建謂詞
例子:
let pre = NSPredicate.init(format: "lastName like[c] 'S*'")
let result = pre.evaluate(with: ["lastName":"sss"])
print(result)// true
var prefix = "prefix"
var suffix = "suffix"
let pre = NSPredicate.init(format: "lastName like[c] %@", "\(prefix + "*" + suffix)")
let result = pre.evaluate(with: ["lastName":"prefixxxxxxsuffix"])
print(result)// true
/// 數字,bool 類型需要用NSNumberv包裹
let pre = NSPredicate.init(format: "age > %@",NSNumber.init(value: 20))
let result = pre.evaluate(with: ["age":30])
print(result)// true
如果要指定動態屬性名稱,請在格式字符串中使用%K,如以下片段所示。
由於使用%@將字符串變量替換爲格式字符串時,字符串變量用引號引起來,因此您不能使用%@指定動態屬性名稱,如以下示例所示
var key = "name"
var value = "abc"
let pre = NSPredicate.init(format: "%@ like %@",key,value)
let result = pre.evaluate(with: ["name":"abc"])
print(result)// false
上面這種情況下,謂詞格式字符串的值爲“name”(注意是帶雙引號的)
也就是format字符串是 “ “name” like xx 所以匹配結果是false
將key 部分的%@ 換成%K 就能正確匹配
var key = "name"
var value = "abc"
let pre = NSPredicate.init(format: "%K like %@",key,value)
let result = pre.evaluate(with: ["name":"abc"])
print(result)// true
NSComparisonPredicate和NSCompoundPredicate提供方便的方法,使您可以輕鬆地分別創建複合謂詞和比較謂詞。 NSComparisonPredicate提供了許多運算符,從簡單的相等性測試到自定義函數。詳系可以看Creating Predicates Directly in Code
謂詞的使用
判斷是否符合謂詞 可以使用NSPredicate方法evaluateWithObject:並傳入要對其評估謂詞的對象。也可以將謂詞與任何對象類一起使用,但是該類必須支持要在謂詞中使用的鍵的鍵值編碼(key-value coding)。
- 在數組中使用謂詞
//filtered 是NSArray中的方法,swift中的Array沒有這個方法,Array 可以使用filter(isIncluded: (String) throws -> Bool )
let array = NSArray.init(array: ["Nick", "Ben", "Adam", "Melissa"])
let pre = NSPredicate.init(format: "SELF beginswith[c] 'b'")
let result = array.filtered(using: pre)
print(result)//[Ben]
- Key-Paths 使用 謂詞
//KVC的類必須繼承自NSObject,變量並且用@objc修飾,否則直接報錯
class Person:NSObject{
@objc var age = 10
}
var person = Person()
let pre = NSPredicate.init(format: "age < %@",NSNumber(value: 20))
let result = pre.evaluate(with: person)
print(result)//true
- 篩選nil值
let arr = NSArray.init(array: [["name":"小明"],["name":"小紅","age":20]])
let pre = NSPredicate.init(format: "age != nil")
let result = arr.filtered(using: pre)
print(result)
/*
[{
age = 20;
name = "\U5c0f\U7ea2";
}]
*/
- CoreData 使用謂詞
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employee"
inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSNumber *salaryLimit = <#A number representing the limit#>;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"salary > %@", salaryLimit];
[request setPredicate:predicate];
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
- 使用正則表達式
let predicate = NSPredicate(format: "SELF MATCHES %@" ,"\\d*")
let result = predicate.evaluate(with: "123456789")
print(result)//true
let predicate = NSPredicate(format: "(name matches %@)&&(age matches %@)" ,"[a-z]*","\\d*")
let result = predicate.evaluate(with: ["name":"abcd","age":"20"])
print(result)//true
謂詞format
-
比較符號,都是針對於左邊表達式和右邊表達式
- > 大於
- > =大於等於
- < 小於
- <=小於等於
- ==等於
- != 或者<> 不等於
- BETWEEN 介於兩者之間,包括上下限
-
複合比較
- && 或者AND 邏輯與
- || 或者 OR 邏輯或
- !或者NOT 邏輯非
-
字符串比較
- BEGINSWITH 左邊表達式以右邊表達式開頭
- CONTAINS 左邊表達式包含右邊表達式
- ENDSWITH 左邊表達式以右邊表達式結尾
- LIKE 左邊表達式和右邊表達式相似(簡單的正則表達式匹配,?匹配一個字符,*匹配0個或者多個字符)
- MATCHES 可以實現較爲複雜的曾則表達式匹配
- 用方括號加cd來不區分大小寫和變音符號
- IN 左邊的表達式在右邊的集合裏
- UTI-CONFORMS-TO該運算符的左側參數是一個表達式,其計算結果爲您要匹配的通用類型標識符(UTI)。 右側參數是一個表達式,其計算結果爲UTI。 如果左側表達式返回的UTI符合右側表達式返回的UTI,則比較的結果爲TRUE。有關哪些類型符合給定類型的信息,請參見《統一類型標識符參考》中的系統聲明的統一類型標識符
- UTI-EQUALS 該運算符的左側參數是一個表達式,其計算結果爲您要匹配的通用類型標識符(UTI)。 右側參數是一個表達式,其計算結果爲UTI。 如果左側表達式返回的UTI等於右側表達式返回的UTI,則比較結果爲TRUE。
-
集合操作
- ANY,SOME
指定以下表達式中的任何元素。例如,任何child.age <18。 - ALL
指定以下表達式中的所有元素。例如,所有children.age <18。 - NONE
不指定以下表達式中的任何元素。例如,NONE children.age <18。這在邏輯上等效於NOT(ANY …)。 - IN
等效於SQL IN操作,左側必須出現在右側指定的集合中。
例如,命名爲IN {‘Ben’,‘Melissa’,‘Nick’}。集合可以是數組,集合或字典,如果是字典,則使用其值。 - array[index]
指定數組數組中指定索引處的元素。 - array[FIRST]
指定數組數組中的第一個元素。 - array[LAST]
指定數組數組中的最後一個元素。 - array[SIZE]
指定數組數組的大小。
- ANY,SOME
-
文字操作
單引號和雙引號產生相同的結果,但它們不會彼此終止。 例如,“ abc”和“ abc”相同,而“a’b’c”等效於a,“ b”,c的以空格分隔的串聯。- FALSE,NO
邏輯錯誤。 - TRUE ,YES
邏輯上正確。 - NULL,NIL
空值。 - SELF
表示被評估的對象。 - “text”
字符串。 - ‘text’
字符串。 - 逗號分隔的文字數組
例如,{‘逗號’,‘分隔’,‘文字’,‘數組’}。 - 標準整數和定點表示法
例如1、27、2.71828、19.75。 - 浮點數與指數
例如9.2e-5。 - 0x
用於表示十六進制數字序列的前綴。 - 0o
用於表示八進制數字序列的前綴。 - 0b
用於表示二進制數字序列的前綴。
- FALSE,NO