NSPredicate 的一些用法

對數(shù)組進(jìn)行過濾

// 返回值是原數(shù)組
[mutableArray filterUsingPredicate:/*NSPredicate*/];
// 返回新的數(shù)組
[mutableArray filteredArrayUsingPredicate:/*NSPredicate*/];

初始化

雖然 predicate 可以從 NSExpression、NSCompoundPredicateNSComparsionPredicate 中實例化,但它還可以用一個字符串的語法生成。這和可視化格式語言類似,我們可以用它定義排版約束。

//  USERIDS 是一個包含 userId 的集合
//  查詢 employees <People集合> 中的 identifier 在 USERIDS的
NSPredicate *morningAttendees = [NSPredicate predicateWithFormat:@"SELF.identifier IN %@", USERIDS];

NSArray *peopleAttendingMorningEvent = [employees filteredArrayUsingPredicate:morningAttendees];

NSPredicate 引入了 keypath來做匹配

[NSPredicate predicateWithFormat:@"SELF.%K IN %@", @"identifier", peopleAttendingMorningEvent];

假設(shè)我們還需要像上面一樣找到所有參加活動的人,但還要滿足他們的工資水平在 50000 到 60000 之間。

[NSPredicate predicateWithFormat:@"SELF.identifier IN %@ && SELF.paygrade.integerValue BETWEEN {50000, 60000}", peopleAttendingMorningEvent];

為了提高可讀性,符號和字符是都支持的
&&AND
||OR
!NOT

比較

CONTAINS 包含 x
BEGINSWITH 以 x 開始
ENDSWITH 以 x 結(jié)束
LIKE 模糊匹配

// 查詢 self.name 是以 `K`開頭的
[NSPredicate predicateWithFormat:@"SELF.name BEGINSWITH 'K'"];
// 查詢是以 Kar* 來模糊匹配的
[NSPredicate predicateWithFormat:@"SELF.name LIKE 'Kar*'"];
// 復(fù)合查詢
NSString *predicateFormat = @"(SELF.name LIKE 'Kar*') AND (SELF.paygrade.intValue >= 10)";
NSPredicate *namesStringWithK = [NSPredicate predicateWithFormat:predicateFormat];

同樣的也支持 正則表達(dá)式

// phoneNumberRegex 手機(jī)號正則
[NSPredicate predicateWithFormat:@"SELF.phoneNumber MATCHES %@", phoneNumberRegex];

為了安全可以結(jié)合 NSStringFromSelector一起使用

NSString *predicateFormat = @"(SELF.%@ LIKE 'Kar*') AND (SELF.paygrade.intValue >= 10)"
NSString *kpName = NSStringFromSelector(@selector(identifier));  
NSString *kpPaygrade = NSStringFromSelector(@selector(paygrade));
NSPredicate *namesStartingWithK = [NSPredicate predicateWithFormat:predicateFormat, kpName, kpPaygrade];
// 現(xiàn)在只有 Karl 了
[mutablePersonAr filterUsingPredicate:namesStartingWithK];

KeyPath 集合查詢

// 假設(shè)一個 Person 對象現(xiàn)在有一個下面的屬性:
// NSArray *previousPay

// 找到所有滿足過去工資的平均值大于 10 的人
NSString *predicateFormat = @"SELF.previousPay.@avg.doubleValue > 10";
NSPredicate *previousPayOverTen = [NSPredicate predicateWithFormat:predicateFormat];

// 所有過去工資的平均值大于 10 的人
[mutablePersonAr filterUsingPredicate:previousPayOverTen];

@avg 均值
@sum 求和
@max 最大值
@min 最小值
@count 數(shù)量

數(shù)組的深入探討

array[FIRST] array[LAST] array[SIZE] array[index]

// 找到所有過去有三份不同工資的人
NSString *predicateFormat = @"previousPay[SIZE] == 3";

NSPredicate *threePreviousSalaries = [NSPredicate predicateWithFormat:predicateFormat];

// 這些 Person 對象過去有三份不同的工資
[mutablePersonAr filterUsingPredicate:threePreviousSalaries];
// 找到所有過去有三個不同的工資以及第一份工資大于 8 的人
NSString *predicateFormat = @"(previousPay[SIZE] == 3) AND (previousPay[FIRST].intValue > 8)";

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat];
[mutablePersonAr filterUsingPredicate:predicate];

更復(fù)雜的情況

@distinctUnionOfArrays
@unionOfArrays
@unionOfObjects
@distinctUnionOfObjects

// 假設(shè) p1/2/3/4 都是 Person 對象
NSArray <P*> *previousEmployees = @[@[p1],@[p2,p1,p2],@[p1],@[p4,p2],@[p4],@[p4],@[p1]];

// 獲取所有不同的 ID
NSArray *unqiuePreviousEmployeeIDs = [previousEmployees valueForKeyPath:@"@distinctUnionOfObjects.identifier"];

// 現(xiàn)在數(shù)組里應(yīng)該只含有不同的 ID

子查詢

// 假設(shè) Person 對象有了一個新的屬性表示他們的隊伍:
// NSArray  *team;
  
// 從雇員數(shù)組中找出這樣的人,他們的團(tuán)隊中有人滿足這個條件:沒有歷史工資數(shù)據(jù)并且工資大于 1
NSString *predicateFormat = @"SUBQUERY(team, $teamMember, $teamMember.paygrade.intValue > 1 AND $teamMember.previousPay == nil).@count > 0";

NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFormat];
[employeeAr filterUsingPredicate:predicate];
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容