NSPredicate的使用

NSPredicate是一个Foundation类,它指定数据被获取或者过滤的方式。它的查询语言就像SQL的WHERE和正则表达式的交叉一样,提供了具有表现力的,自然语言界面来定义一个集合被搜寻的逻辑条件。

比较运算

// =,==:判断两个表达式是否相等,
NSNumber *testNumber = @123;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];
NSLog(@"%@ vs 123: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"相等" : @"不相等"));

2018-03-05 15:50:47.768 DemoNSPredicate[2472:315182] 123 vs 123: 相等
// >=,=>:判断左边表达式的值是否大于或等于右边表达式的值
predicate = [NSPredicate predicateWithFormat:@"SELF >= 200"];
NSLog(@"%@ vs 200: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"大于等于" : @"小于"));

2018-03-05 15:50:47.768 DemoNSPredicate[2472:315182] 123 vs 200: 小于
// <=,=<:判断右边表达式的值是否小于或等于右边表达式的值
predicate = [NSPredicate predicateWithFormat:@"SELF <= 150"];
NSLog(@"%@ vs 150: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"小于等于" : @"大于"));

2018-03-05 15:50:47.768 DemoNSPredicate[2472:315182] 123 vs 150: 小于等于
// >:判断左边表达式的值是否大于右边表达式的值
predicate = [NSPredicate predicateWithFormat:@"SELF > 123"];
NSLog(@"%@ vs 123: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"大于" : @"小于等于"));

2018-03-05 15:50:47.768 DemoNSPredicate[2472:315182] 123 vs 123: 小于等于
// <:判断左边表达式的值是否小于右边表达式的值
predicate = [NSPredicate predicateWithFormat:@"SELF < 123"];
NSLog(@"%@ vs 123: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"小于" : @"大于等于"));

2018-03-05 15:50:47.769 DemoNSPredicate[2472:315182] 123 vs 123: 大于等于
// !=、<>:判断两个表达式是否不相等
predicate = [NSPredicate predicateWithFormat:@"SELF != 123"];
NSLog(@"%@ vs 123: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"不相等" : @"相等"));

2018-03-05 15:50:47.769 DemoNSPredicate[2472:315182] 123 vs 123: 相等
// BETWEEN:BETWEEN表达式必须满足表达式 BETWEEN {下限,上限}的格式,要求该表达式必须大于或等于下限,并小于或等于上限
predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];
NSLog(@"%@ vs {100, 200}: %@", testNumber, ([predicate evaluateWithObject:testNumber] ? @"包含" : @"不包含"));

2018-03-05 15:50:47.769 DemoNSPredicate[2472:315182] 123 vs {100, 200}: 包含

逻辑运算

NSArray *testArray = @[@1, @2, @3, @4, @5, @6];

// AND、&&:逻辑与,要求两个表达式的值都为YES时,结果才为YES。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];
NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"元素值大于2,且小于5的数组:%@", filterArray);
    
// OR、||:逻辑或,要求其中一个表达式为YES时,结果就是YES
predicate = [NSPredicate predicateWithFormat:@"SELF < 2 || SELF > 5"];
filterArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"元素值小于2,或大于5的数组:%@", filterArray);
    
// NOT、 !:逻辑非,对原有的表达式取反
predicate = [NSPredicate predicateWithFormat:@"NOT (SELF > 2 AND SELF < 5)"];
filterArray = [testArray filteredArrayUsingPredicate:predicate];
NSLog(@"元素值既不大于2也不小于5,即小于等于2,或大于等于5:%@", filterArray);

2018-03-05 15:52:47.475 DemoNSPredicate[2472:315182] 元素值大于2,且小于5的数组:(
    3,
    4
)
2018-03-05 15:52:47.476 DemoNSPredicate[2472:315182] 元素值小于2,或大于5的数组:(
    1,
    6
)
2018-03-05 15:52:47.476 DemoNSPredicate[2472:315182] 元素值既不大于2也不小于5,即小于等于2,或大于等于5:(
    1,
    2,
    5,
    6
)

字符串比较运算

NSString *text = @"devZhang";
// BEGINSWITH:检查某个字符串是否以指定的字符串开头(如判断字符串是否以a开头:BEGINSWITH 'a')
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH 'd'"];
NSLog(@"%@ beginWith d: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.048 DemoNSPredicate[2472:315182] devZhang beginWith d: 1
// ENDSWITH:检查某个字符串是否以指定的字符串结尾
predicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH 'a'"];
NSLog(@"%@ endWith a: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.048 DemoNSPredicate[2472:315182] devZhang endWith a: 0
// CONTAINS:检查某个字符串是否包含指定的字符串
predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'evZ'"];
NSLog(@"%@ 包含 evZ: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.048 DemoNSPredicate[2472:315182] devZhang 包含 evZ: 1
// LIKE:检查某个字符串是否匹配指定的字符串模板。其之后可以跟?代表一个字符和*代表任意多个字符两个通配符。比如"name LIKE '*ac*'",这表示name的值中包含ac则返回YES;"name LIKE '?ac*'",表示name的第2、3个字符为ac时返回YES。
predicate = [NSPredicate predicateWithFormat:@"SELF LIKE '?evZ*g'"];
NSLog(@"%@ like ?evZ*g: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.049 DemoNSPredicate[2472:315182] devZhang like ?evZ*g: 1
// MATCHES:匹配,即检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。
// 判断字符串是否以d字符开头,g字符结尾
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^d.+g$'"];
NSLog(@"%@ match d开头/g结尾: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.049 DemoNSPredicate[2472:315182] devZhang match d开头/g结尾: 1
// 判断字符串是否为1~20位的字母字符串(没有位数限制时,可写成"[a-zA-Z]{1,}",或"[a-zA-Z]+")
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '[a-zA-Z]{1,20}'"];
NSLog(@"%@ match 1~20位字母: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.049 DemoNSPredicate[2472:315182] devZhang match 1~20位字母: 1
// 判断字符串是否以下划线开头包含数字和字母的6~12位
text = @"_168devZhang";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^_+[0-9]+[a-zA-Z]{6,12}'"];
NSLog(@"%@ match 下划线开头+数字+字母+6~12位: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.050 DemoNSPredicate[2472:315182] _168devZhang match 下划线开头+数字+字母+6~12位: 1
// 判断字符串长度
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '([a-zA-Z0-9._&*]{8,16})'"];
NSLog(@"%@ match 8~16位: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.050 DemoNSPredicate[2472:315182] _168devZhang match 8~16位: 1
// 判断数字带两位小数
text = @"123.22";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^[0-9]+(.[0-9]{2})'"];
NSLog(@"%@ match 数字带两位小数: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.050 DemoNSPredicate[2472:315182] 123.22 match 数字带两位小数: 1
/**
     * 手机号码
     * 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 联通:130,131,132,152,155,156,185,186
     * 电信:133,1349,153,180,189
*/
text = @"13511113244";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^1(34[0-8]|(3[5-9]|5[017-9]|8[278]))[0-9]{8}$|^1(3[0-2]|5[256]|8[56])[0-9]{8}$|^1(33|53|8[09])[0-9]{8}|^1(349)[0-9]{7}'"];
NSLog(@"%@ match 手机号码: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.050 DemoNSPredicate[2472:315182] 13511113244 match 手机号码: 1
// 中国移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^1(34[0-8]|(3[5-9]|5[017-9]|8[278]))[0-9]{8}$'"];
NSLog(@"%@ match 中国移动手机号码: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.051 DemoNSPredicate[2472:315182] 13511113244 match 中国移动手机号码: 1
// 中国联通:130,131,132,152,155,156,185,186
text = @"18555551155";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^1(3[0-2]|5[256]|8[56])[0-9]{8}$'"];
NSLog(@"%@ match 中国联通手机号码: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.051 DemoNSPredicate[2472:315182] 18555551155 match 中国联通手机号码: 1
// 中国电信:133,1349,153,180,189
text = @"13498161155";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^1(33|53|8[09])[0-9]{8}|^1(349)[0-9]{7}'"];
NSLog(@"%@ match 中国电信手机号码: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.051 DemoNSPredicate[2472:315182] 13498161155 match 中国电信手机号码: 1
/**
     * 大陆地区固话及小灵通
     * 区号:010,020,021,022,023,024,025,027,028,029,0755,0753,……
     * 号码:七位或八位
*/
text = @"075522222222";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '^0(10|2[05789])[1-9]{8}|^0[0-9]{3}[0-9]{7,8}'"];
NSLog(@"%@ match 固定电话: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.051 DemoNSPredicate[2472:315182] 075522222222 match 固定电话: 1
// 验证email
text = @"zhangsy@163.com";
predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}'"];
NSLog(@"%@ match 电子邮箱: %d", text, [predicate evaluateWithObject:text]);

2018-03-05 15:54:59.052 DemoNSPredicate[2472:315182] zhangsy@163.com match 电子邮箱: 1

集合运算

NSArray *filterArray = @[@"ab", @"abc"];
NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];
// 元素值未包含
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];
NSArray *resultArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"未包含在集合中的数组:%@", resultArray);

2018-03-05 15:59:59.412 DemoNSPredicate[2472:315182] 未包含在集合中的数组:(
    a,
    abcd
)
// 判断元素值大于等于某个值
array = @[@"2", @"3", @"4", @"5"];
predicate = [NSPredicate predicateWithFormat:@"integerValue >= %@", @(3)];
resultArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"元素值大于某个值:%@", resultArray);

2018-03-05 15:59:59.412 DemoNSPredicate[2472:315182] 元素值大于某个值:(
    3,
    4,
    5
)
// 判断元素值
NSMutableArray *personArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++)
{
        PersonModel *person = [[PersonModel alloc] init];
        person.name = [NSString stringWithFormat:@"name_%@", @(i)];
        person.age = @(arc4random() % 50 + 10 + i);
        
        [personArray addObject:person];
}
NSLog(@"personArray = %@", personArray);
array = [NSArray arrayWithArray:personArray];
predicate = [NSPredicate predicateWithFormat:@"age >= %@", @(30)];
resultArray = [array filteredArrayUsingPredicate:predicate];
NSLog(@"resultArray = %@", resultArray);

2018-03-05 15:59:59.412 DemoNSPredicate[2472:315182] personArray = (
    "<PersonModel: 0x600000242be0>",
    "<PersonModel: 0x600000243270>",
    "<PersonModel: 0x600000242dc0>",
    "<PersonModel: 0x600000243570>",
    "<PersonModel: 0x600000242b80>",
    "<PersonModel: 0x6000002425e0>",
    "<PersonModel: 0x6000002435d0>",
    "<PersonModel: 0x6000002426a0>",
    "<PersonModel: 0x6000002430c0>",
    "<PersonModel: 0x600000243540>"
)

PersonModel

#import <Foundation/Foundation.h>

@interface PersonModel : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *address;
@property (nonatomic, strong) NSString *job;
@property (nonatomic, strong) NSNumber *age;

@end
#import "PersonModel.h"

@implementation PersonModel

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

推荐阅读更多精彩内容

  • 原文链接:http://www.jianshu.com/p/b2694972863e iOS Predicate ...
    wintersal阅读 824评论 0 49
  • 最近在看一个开源项目,里面用到了NSPredicate类,感觉Foundation提供的NSPredicate类及...
    sunshinelww阅读 1,440评论 0 0
  • | NSPredicate是什么?NSPredicate 是预测的意思 但是我们常翻译成谓词 | 它可以干什么?使...
    努力奔跑的小男孩阅读 380评论 0 0
  • 在我们写程序中往往会遇到一些查找的操作,比如一个数组里面全是PersionModel,如果要找出年龄大于40岁的如...
    liangZhen阅读 1,376评论 0 1
  • 创建一个测试的表 插入几条数据 看一下现在表的样子 输出 执行交换语句 再看一下交换后表的样子 输出 交换成功 h...
    rowsy阅读 1,649评论 0 0