转【iOS开发技术】NSPredicate谓词的用法 数组过滤

NSPredicate是什么

NSPredicate:谓词

字面翻译是这个意思,但是我觉得谓词这个词太难以理解了

NSPredicate的具体用途应该还是过滤,类似于过滤条件之类的,相当于一个主语的谓语,所以说会是谓词这个名字。(我是这么理解的)

NSPredicate的创建

我们看到创建谓词使用类方法predicateWithFormat: (NSString*) format,format 里的东西真的

和SQL 的where 条件差不多。

另外,参数format 与NSLog 的格式化模版差不多,如果1 和

188.0 是传递过来的参数,你可以写成如下的形式:

@"pid>%d and height<%f",1,188.0

NSPredicate中主要的几种运算方式

1.比较运算符 > 、< 、== 、 >= 、<= 、 !=

例:@"number >= 99"

2.逻辑运算符:AND、OR、NOT 这几个运算符计算并、或、非的结果。

3.范围运算符:IN 、BETWEEN

例:@"number BETWEEN {1,5}"

@"address IN {'shanghai','nanjing'}"

4.字符串本身:SELF

例:@"SELF == 'APPLE'"

5.字符串相关:BEGINSWITH、ENDSWITH、CONTAINS

例: @"name CONTAIN[cd] 'ang'" //包含某个字符串

@"name BEGINSWITH[c] 'sh'" //以某个字符串开头

@"name ENDSWITH[d] 'ang'" //以某个字符串结束

注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。

6.通配符:LIKE

例:@"name LIKE[cd] '*er*'" //*代表通配符,Like也接受[cd].

@"name LIKE[cd] '???er*'"

7.正则表达式:MATCHES

例:NSString *regex = @"^A.+e$"; //以A开头,e结尾

@"name MATCHES %@",regex

如何使用NSPredicate对一个自定义实体进行筛选

NSPredicate我暂时都是用于过滤的,否则我们过滤就需要自己写判断 写循环,去判断输出了。

接下来就上代码和例子吧。

建立一个实体类 Dog

@property (copy  , nonatomic) NSString* name;

@property (assign , nonatomic) int      age ;

这样我们就有一个类了

我们创建 5只Dog的实体

Dog * dog1=[Dog news];dog1.name=@"这是第一只Dog";dog1.age=@"11";

Dog * dog2=[Dog news];dog2.name=@"这是第二只Dog";dog2.age=@"22";

Dog * dog3=[Dog news];dog3.name=@"这是第三只Dog";dog3.age=@"33";

Dog * dog4=[Dog news];dog4.name=@"这是第四只Dog";dog4.age=@"44";

Dog * dog5=[Dog news];dog5.name=@"这是第五只Dog";dog5.age=@"55";

不要吐槽我的Dogs的年龄 → 。→

然后我们需要一个Array把他们都装进去

NSArray * dogArr=@[dog1,dog2,dog3,dog4,dog5];

酱紫所有的Dog都装到一个数组里了

使用NSPredicate的筛选

没有使用NSPredicate的筛选应该大家都会写,循环+判断。。。

使用NSPredicate的筛选

具体使用的代码

//创建谓词的对象 谓词条件是基于KVC的,所以需要说明一点,加入Dog里面有个属性是Doginfo指向Doginfo类,在使用的时候 我们的条件就要写成Doginfo.xxx了。

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name=='这是第一只Dog' AND age ==11"];

for(Dog * d in dogArr)

{

if([predicate evaluateWithObject:d])

{

NSLog(d.name);

}

}

以上的代码打印出来的结果就是 这是第一只Dog

NSPredicate筛选一个对象逻辑还是很清晰的,不过这里比较麻烦的就是 还有一个循环,这里我们会发现数组提供了一个方法可以更方便的检索数组对象

直接筛选出一个符合谓词的新数组。

NSPredicate *pre = [NSPredicate predicateWithFormat:@"age >11"];

NSMutableArray *arrayPre=[dogArr filteredArrayUsingPredicate: pre];

arrayPre里面的对象就会是 除了dog1之外的所有的dog。(至于为什么看我的条件...)

看到这里发现NSPredicate 可以用于自定义的实体的检索、筛选,那如果用于 NSString,NSInteger,bool呢?那我们再看一段代码吧

NSArray *arrays=[NSArray arrayWithObjects: @"Apple", @"Google", @"MircoSoft", nil];

NSPredicate *pre2 = [NSPredicate predicateWithFormat:@"SELF=='Apple'"];

上面这段代码是匹配字符串的时候 NSPredicate 需要如何声明

使用NSPredicate在两个数组之间进行差异筛选

NSArray* array = @[@"aa",@"bb"];

NSArray* array2 = @[@"aa",@"bb",@"cc",@"dd"];

NSPredicate* thePredicate = [NSPredicate predicateWithFormat:@"NOT(SELF in %@)",array];

NSArray* arr3 = [array2 filteredArrayUsingPredicate:thePredicate];

NSLog(@"%@",arr3);

上面的代码输出结果 arr3={@"cc" ,@"dd"}

这样大家就很容易理解了

SELF在前面有介绍过 可以往回翻阅一下

如何使用正则筛选一个数组

NSString *regex = @"^A.+e$";//以A 开头,以e 结尾的字符。

NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];

if([pre evaluateWithObject: @"Apple"]){

printf("YES\n");

}else{

printf("NO\n");

}

关于NSPredicate的其他说明和注意事项,以及技巧

动态属性名

假如你的代码如下

NSPredicate *p = [NSPredicate predicateWithFormat:@"name = %@", @"name1"];

显然代码没有任何问题,但是这个不是最好的写法我建议如下写法:

NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];

NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:

@"name1", @"NAME",nil];

NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];

这样看上去可能会让代码逻辑更清晰。

当过滤条件字段都是动态的时候

NSString *key = @"name";

NSString *value = @"name1";

NSPredicate *p = [NSPredicate predicateWithFormat:@"%@ = %@", key, value];

然后当你执行到第三行的时候代码就会报错!

逻辑上没错误啊!!!为什么会出错呢?

NSPredicate要自动添加引号,所以最后得到的格式应该是@"'name' = 'name1'"。明显不对。要做的就是:

NSPredicate *p = [NSPredicate predicateWithFormat:@"%K = %@", key, value];

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

推荐阅读更多精彩内容

  • 首先,我们需要知道何谓谓词,让我们看看官方的解释:The NSPredicate class is used to...
    旭日飞扬阅读 1,514评论 0 0
  • 转载自:http://www.cocoachina.com/ios/20160111/14926.html 1、大...
    一笔春秋阅读 2,840评论 0 2
  • 面试笔试都是必考语法知识的。请认真复习和深入研究OC。 Objective-C 方法和选择器有何不同?(Diffe...
    b485c88ab697阅读 5,683评论 0 35
  • 这些日子,某个擅长压榨别人的朋友寄住在我家,还tm带来了三条狗。我日。还好就快要搬走了。我以后决不允许任何非亲人的...
    涤非阅读 254评论 0 0
  • 今天呢,看的是一本适龄为三岁的绘本,书名为「谁偷了包子?」。 翻开这本书,给我的第一感觉就是浓浓的中国风味,各种胡...
    噗呲噗呲阅读 277评论 0 0