iOS谓词NSPredicate

谓词

首先,我们可以看看官方文档的解释

NSPredicate官方描述

大概意思是: 一种逻辑条件的定义,用于约束查找或者内存中筛选的搜索条件。个人理解就是一个用来匹配查询结果的条件。

NSPredicate的API

// 通过表达式创建谓词实例
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;

// 表达式中的%@从arguments中取值
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat argumentArray:(nullable NSArray *)arguments;

// 表达式中的%@占位符将从argList中取值
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat arguments:(va_list)argList;

// 通过一个元数据查询字符串来创建谓词实例,仅macos可以使用
+ (nullable NSPredicate *)predicateFromMetadataQueryString:(NSString *)queryString API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos);

// 创建一个固定结果为BOOL值的谓词实例
+ (NSPredicate *)predicateWithValue:(BOOL)value;    

// 根据block的回调的返回值创建一个结果为YES/NO的谓词实例
+ (NSPredicate*)predicateWithBlock:(BOOL (^)(id _Nullable evaluatedObject, NSDictionary<NSString *, id> * _Nullable bindings))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

// 获取谓词的表达式,只读属性
@property (readonly, copy) NSString *predicateFormat;    

// 用常量值代替变量,用字典中的键值对替换用$声明的变量
- (instancetype)predicateWithSubstitutionVariables:(NSDictionary<NSString *, id> *)variables;    // substitute constant values for variables

// 比较评估对象是否符合谓词
- (BOOL)evaluateWithObject:(nullable id)object;    

// 比较评估对象是否符合谓词
- (BOOL)evaluateWithObject:(nullable id)object substitutionVariables:(nullable NSDictionary<NSString *, id> *)bindings API_AVAILABLE(macos(10.5), ios(3.0), watchos(2.0), tvos(9.0)); 

// 强制使用已安全解码的谓词以进行评估
- (void)allowEvaluation API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); 

常用方法

上面官方暴露的API我们可以看到创建NSPredicate基本都需要一个表达式

创建谓词

 NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'world'"];
 NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@", @"world"];
 NSPredicate *predicate3 = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@" argumentArray:@[@"world"]];
 NSLog(@"predicate1谓词表达式:%@", predicate1.predicateFormat);
 NSLog(@"predicate2谓词表达式:%@", predicate2.predicateFormat);
 NSLog(@"predicate3谓词表达式:%@", predicate3.predicateFormat);

打印结果为:
谓词创建实例比较

创建谓词并使用

NSString *str = @"Hello, world";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'world'"];
NSLog(@"谓词评估结果:%hhd",[predicate evaluateWithObject:str]);

打印结果为:谓词评估结果:1

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS $variable"];
predicate = [predicate predicateWithSubstitutionVariables:@{@"variable":@"world"}]; NSLog(@"谓词表达式为%@", [predicate predicateFormat]);
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSArray * _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
      // 通过evaluatedObject和bindings来判断是否过滤
      if ([evaluatedObject containsObject:[bindings objectForKey:@"key"]]) {
            return YES;
      } else {
          return NO;
       }
}];
BOOL result = [predicate evaluateWithObject:@[@"1", @"2"] substitutionVariables:@{@"key":@"2"}];
NSLog(@"谓词评估结果%hhd", result);

NSPredicate的扩展

@interface NSArray<ObjectType> (NSPredicateSupport)

// 对数组中所有元素进行谓词评估,返回数组
- (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 

@end
@interface NSMutableArray<ObjectType> (NSPredicateSupport)
// 移除所有不符合谓词评估的数组元素
- (void)filterUsingPredicate:(NSPredicate *)predicate; 
@end

NSSet相关类中也有类似的方法,使用与数组这边雷同。

谓词表达式语法

可以在关键字后面加在[cd],c表示忽略大小写,即CAFE与cafe为相同字符串;d表示忽略读音,即café与cafe为相同字符串。

常用字面语义

表达式 用途
SELF 谓词评估的对象
'text' 字符串text,使用双引号需要转义符\
TRUE、YES 逻辑真
FALSE、NO 逻辑假
占位符
表达式 用途
%K 属性名
%@ 属性值
NSString *name = @"name";
NSString *value = @"value";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", name, value];
NSLog(@"谓词表达式%@", [predicate predicateFormat]);
BOOL result = [predicate evaluateWithObject:@{@"name" : @"value111"}];
NSLog(@"谓词结果为%hhd", result);

输出结果为:谓词表达式name CONTAINS "value"

                  **谓词结果为1**

基本比较运算

表达式 用途
=、== 等于
>=、 => 大于或等于
<=、=< 小于或等于
> 大于
< 小于
!=、<> 不等于
BETWEEN 值在区间内(包含边界数值)

这边附上一个BETWEEN的使用例子

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {200, 250}"];
NSLog(@"谓词评估结果:%hhd",  [predicate evaluateWithObject:@(212)]); // 谓词评估结果:1

布尔值

表达式 用途
TRUEPREDICATE
FALSEPREDICATE

[NSPredicate predicateWithValue:YES]的表达式实际上就是TRUEPREDICATE

逻辑运算
表达式 用途
AND、&&
OR、||
NOT、!
字符串比较
表达式 用途
BEGINSWITH 字符串以...开始
ENDSWITH 字符串以...结束
CONTAINS 字符串包含...
LIKE 字符串相等
MATCHES 字符串匹配右边的正则表达式
集合操作
表达式 用途
ANY、SOME 集合中是否至少有一个元素满足条件
ALL 集合中所有元素满足条件
NONE 集合中所有元素均不满足条件
IN 被集合包含
SELF[index] 取对应索引的元素
SELF[FIRST] 第一个元素
SELF[LAST] 最后一个元素
SELF[SIZE] 元素的个数
SELF['key']或SELF.key或key 字典对应key的元素

参考链接1

参考链接2

如有错误,欢迎指正

iOS开发QQ交流群:568571839,欢迎来撩~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容