谓词的主干使用,iOS中的过滤器和正则表达式
分类:计算机编程

图片 1效果图

iOS中的过滤器和正则表明式(NSPredicate,NSRegularExpression),nspredicate正则

参谋链接:

NSPredicate

Cocoa提供了一个NSPredicate类,它用来钦点过滤器的法规

初阶化方法

 (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;

Format:

/**
 1.格式表明符
 %d和%@等插入数值和字符串,%K代表key
 还足以引进变量名,用$,类似景况变量,如:@"name == $NAME",再用predicateWithSubstitutionVariables调用来布局新的谓词(键/值字典),在那之中键是变量名,值是要插入的内容,注意这种情状下无法把变量当成键路线,只可以用作值
 2.运算符
 
 ==等于
 
 >:大于
 
 >=和=>:大于或等于
 
 <:小于
 
 <=和=<:小于或等于
 
 !=和<>:不等于
 
 括号和逻辑运算AND、ORAV4、NOT或然C样式的等效表达式&&、||、!
 
 注意:不等号适用于数字和字符串
 
 
 3. 数组运算符
 BETWEEN和IN后加有个别数组,能够用{50,200},也得以用%@格式表明符插入自个儿的靶子,也能够用变量
 
 4.SELF足够了
 self就象征对象自己
 
 5.字符串运算符
 BEGINSWITH:以有个别字符串开端
 
 ENDSWITH:以有个别字符串截止
 
 CONTAINS:满含某些字符串
 @"name ENDSWITH[d] 'ang'"
 
 [c],[d],[cd],后缀表示不区分轻重缓急写,不区分发音符号,两以此都不区分

 6.LIKE运算符
 
 类似SQL的LIKES
 
 LIKE,与通配符“*”表示任意多和“?”表示三个整合使用
 
 LIKE也接受[cd]符号
 
 7.MATCHES能够行使正则表明式
 NSString *regex = @"^A. e$";   //以A开头,e结尾
 */

 

数组的类目:用来过滤数组

- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 

 可变数组能够向来过滤

- (void)filterUsingPredicate:(NSPredicate *)predicate; 

 例:过滤出数组中的字符串中包含ang的成分

    NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan", nil];
    NSString *string = @"ang";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];
    NSLog(@"%@",[array filteredArrayUsingPredicate:pred]);

 单个对象的过滤

- (BOOL)evaluateWithObject:(id)object;

 例:判定字符串中首字母是还是不是字母

  NSString *regex = @"[A-Za-z] ";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    
    if ([predicate evaluateWithObject:@"hahaa"]) {
        NSLog(@"首字母含有字母");
    }else {
        NSLog(@"首字母不含字母");
    }

过滤语句:邮箱过滤@"[A-Z0-9a-z._% -][email protected][A-Za-z0-9.-] \.[A-Za-z]{1,5}";

电话号码部分:@"^1(3[0-9]|5[0-35-9]|8[025-9])\d{8}$"

NSRegularExpression

字符串替换

 NSError* error = NULL;
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"(encoding=")[^"] (")"
                                                                           options:0
                                                                             error:&error];
    NSString* sample = @"<xml encoding="abc"></xml><xml encoding="def"></xml><xml encoding="ttt"></xml>";
    NSLog(@"Start:%@",sample);
    NSString* result = [regex stringByReplacingMatchesInString:sample
                                                       options:0
                                                         range:NSMakeRange(0, sample.length)
                                                  withTemplate:@"$1utf-8$2"];
    NSLog(@"Result:%@", result);

字符串中截取字符串

   //组装一个字符串,要求把内部的网站分析出来
    NSString *urlString=@"<meta/><link/><title>1Q84 BOOK1</title></head><body>";
    
    //NSRegularExpression类里面调用表明的主意供给传递贰个NSError的参数。上边定义三个
    NSError *error;
    
    //http :[^\s]* 这几个表明式是检查测验三个网址的。(?<=title>).*(?=</title)截取html小说中的<title></title>中内文字的正则表明式
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=title\>).*(?=</title)" options:0 error:&error];
    
    if (regex != nil) {
        NSTextCheckingResult *firstMatch=[regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];
        
        if (firstMatch) {
            NSRange resultRange = [firstMatch rangeAtIndex:0];
            
            //从urlString当中截取数据
            NSString *result=[urlString substringWithRange:resultRange];
            //输出结果
            NSLog(@"->%@<-",result);
        }
    }

 NSPredicate测试:

在那之中自定义一个类,出事的时候给属性赋值,用runtime获取具备属性同等对待写description方法

@interface DataModel : NSObject

@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger num;

@end#import "DataModel.h"
#import <objc/runtime.h>

@implementation DataModel

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.name = @"haha";
        self.num = 12;
    }
    return self;
}

//修改描述文件(获取具备属性存成字典)
- (NSString *)description {
    u_int               count;
    objc_property_t*    properties= class_copyPropertyList([self class], &count);
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
    for (int i = 0; i < count ; i )
    {
        const char* propertyName = property_getName(properties[i]);
        NSString *strName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
        [dic setObject:[self valueForKey:strName] forKey:strName];
    }
    return [NSString stringWithFormat:@"<%@ %p>:%@",self.class,&self,dic];
}

 例子:

//(1)相比运算符>,<,==,>=,<=,!=
- (void)test1 {
    DataModel *model = [[DataModel alloc]init];
    //类里面
    /*
     self.name = @"haha";
     self.num = 12;
     */
    //可决断二个类的叁特性质是或不是等于有个别值,字符串是不是等于
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num > 11"];
    BOOL match = [predicate evaluateWithObject:model];
    NSLog(@"%@",match?@"yes":@"no");
}

//强悍的数组过滤效果
- (void)test2 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2 = [[DataModel alloc]init];
    DataModel *model3 = [[DataModel alloc]init];
    model2.num = 8;
    model3.name = @"lala";
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num > 10 AND name == 'lala'"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog(@"过滤出了: %@",mutableArray);
}

//含有变量的谓词,在此处用><会崩溃
- (void)test3 {
    DataModel *model= [[DataModel alloc]init];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == $key"];
    NSDictionary *dic = @{@"key":@"haha"};
    NSPredicate *predicate1 = [predicate predicateWithSubstitutionVariables:dic];
    NSLog(@"%@",predicate1);
    BOOL match = [predicate1 evaluateWithObject:model];
    NSLog(@"%@",match?@"yes":@"no");
}

//BETWEEN
//BETWEEN和IN后加有些数组,能够用{50,200},也得以用%@格式表明符插入本身的对象,也能够用变量
- (void)test4 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2 = [[DataModel alloc]init];
    DataModel *model3 = [[DataModel alloc]init];
    model2.num = 8;
    model3.num = 20;
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num BETWEEN {5,15}"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog(@"过滤出了: %@",mutableArray);
}

//IN运算符

- (void)test5 {
    
    NSArray *arrayFilter = [NSArray arrayWithObjects:@"abc1", @"abc2", nil];
    
    NSMutableArray *arrayContent = [NSMutableArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil];
    
    //过滤出arrayContent 不包含 arrayFilter的元素
    NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter];
    
    [arrayContent filterUsingPredicate:thePredicate];
    NSLog(@"%@",arrayContent);
}

//BEGINSWITH,ENDSWITH,CONTAINS
//LIKE运算符(通配符)
- (void)test6 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2= [[DataModel alloc]init];
    DataModel *model3= [[DataModel alloc]init];
    model1.name = @"a123.png";
    model3.name = @"a.png";
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"name LIKE[cd] 'a*.png'"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog (@"%@", mutableArray);
}

 

参照他事他说加以考察链接: NSPredicate Cocoa提...

参照链接:

先是,我们要求明白何谓谓词,让我们看看官方的表明:The NSPredicate class is used to define logical conditions used to constrain a search either for a fetch or for in-memory filtering.NSPredicate类是用来定义逻辑条件约束的收获或内存中的过滤找寻。能够采取谓词来代表逻辑条件,用于描述对象长久性存款和储蓄在内部存款和储蓄器中的对象过滤。其实意思正是:小编是三个过滤器,不符合条件的都滚开。一、NSPredicate的大旨语法大家选择一门语言,无论是外语依旧Computer语言,总是从语法初阶的,那样我们本事科学的握住逻辑。所以大家从语法开头说到。在这一部分我们仅关怀其语法的施用只要大家利用谓词(NSPredicate)都亟需为谓词定义谓词表明式,而以此表达式必须是多个回来BOOL的值。谓词表明式由表明式、运算符和值构成。1.相比运算符相比较运算符如下=、==:判定七个表明式是或不是等于,在谓词中=和==是同样的野趣都是剖断,而未有赋值这一说NSNumber *testNumber = @123;  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];  if ([predicate evaluateWithObject:testNumber]) {      NSLog(@"testString:%@", testNumber);  }大家得以观看输出的原委为:二零一六-01-07 11:12:27.281 Predicte德姆o[4130:80412] testString:123>=,=>:推断左边表明式的值是或不是超过或等于左侧表明式的值<=,=<:剖断侧面表明式的值是或不是低于或等于左侧表明式的值>:剖断侧面表达式的值是还是不是高出左边表明式的值<:推断左侧表明式的值是不是低于左边表明式的值!=、<>:推断七个表明式是或不是不相等BETWEEN:BETWEEN表明式必得满意表明式 BETWEEN {下限,上限}的格式,供给该表明式必需大于或等于下限,并小于或等于上限NSNumber *testNumber = @123;NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];  if ([predicate evaluateWithObject:testNumber]) {      NSLog(@"testString:%@", testNumber);  } else {      NSLog(@"不符合条件");  }输出结果为:二〇一四-01-07 11:20:39.921 PredicteDemo[4366:85408] testString:1232.逻辑运算符AND、&&:逻辑与,要求七个表明式的值都为YES时,结果才为YES。NSArray *testArray = @[@1, @2, @3, @4, @5, @6];  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF > 2 && SELF < 5"];  NSArray *filterArray = [testArray filteredArrayUsingPredicate:predicate];  NSLog(@"filterArray:%@", filterArray);输出结果为:2015-01-07 11:27:01.885 PredicteDemo[4531:89537] filterArray:(  3,  4)O纳瓦拉、||:逻辑或,要求当中三个表明式为YES时,结果正是YESNOT、 !:逻辑非,对原本的表明式取反3.字符串比较运算符BEGINSWITH:检查有个别字符串是还是不是以内定的字符串最早(如推断字符串是或不是以a起始:BEGINSWITH 'a')ENDSWITH:检查有些字符串是还是不是以钦定的字符串结尾CONTAINS:检查某些字符串是不是含有钦命的字符串LIKE:检查有个别字符串是或不是合作钦点的字符串模板。其随后能够跟?代表叁个字符和*意味着专擅多个字符七个通配符。举个例子"name LIKE '*ac*'",那意味着name的值中包涵ac则赶回YES;"name LIKE '?ac*'",表示name的第2、3个字符为ac时回来YES。MATCHES:检查某些字符串是不是相配钦命的正则表明式。纵然正则表明式的进行功能是最低的,但其功效是最精锐的,也是大家最常用的。注:字符串比较都以分别轻重缓急写和重音符号的。如:café和cafe是区别等的,Cafe和cafe也是区别等的。如若愿意字符串相比运算不区分轻重缓急写和重音符号,请在这么些运算符后使用[c],[d]选项。其中[c]是不区分轻重缓急写,[d]是不区分重音符号,其写在字符串相比较运算符之后,举个例子:name LIKE[cd] 'cafe',那么不论是name是cafe、Cafe照旧café上面的表明式都会回去YES。4.会集运算符ANY、SOME:集合中率性两个要素满意条件,就回去YES。ALL:集结中全体因素都满足条件,才回来YES。NONE:会集中并未有任何因素知足条件就回到YES。如:NONE person.age < 18,表示person群集中具有因素的age>=18时,才回来YES。IN:等价于SQL语句中的IN运算符,独有当左边表达式或值出现在右侧的聚集中才会再次来到YES。大家通过三个例证来看一下NSArray *filterArray = @[@"ab", @"abc"];  NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];  NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);代码的功力是将array春日filterArray中一律的元素去除,输出为:2014-01-07 13:17:43.669 Predicte德姆o[6701:136206] (  a,  abcd)array[index]:重返array数组中index索引处的因素array[FIRST]:重返array数组中首先个因素array[LAST]:再次回到array数组中最终三个因素array[SIZE]:重回array数组巧月素的个数5.直接量在谓词表明式中得以选择如下直接量FALSE、NO:代表逻辑假TRUE、YES:代表逻辑真NULL、NIL:代表空值SELF:代表正在被判别的对象自己"string"或'string':代表字符串数组:和c中的写法一样,如:{'one', 'two', 'three'}。数值:饱含注明、小数和科学计数法表示的花样十六进制数:0x开始的数字八进制:0o初步的数字二进制:0b上马的数字6.保留字下列单词都以保留字(不论大小写)AND、OXC60、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FI路虎极光ST、LAST、SIZE、ANYKEY、SUBQUE奥迪Q3Y、CAST、TRUEPREDICATE、FALSEPREDICATE注:即便尺寸写都足以,可是更推荐应用大写来代表那么些保留字二、谓词的用法1.定义谓词一般我们选择下列格局来定义八个谓词NSPredicate *predicate = [NSPredicate predicateWithFormat:<#(nonnull NSString *), ...#>];下边大家因而多少个简易的例子来拜望它该怎么运用:首先大家须求定义三个模子,因为示例中要求动用它ZLPersonModel.h#importtypedef NS_ENUM(NSInteger, ZLPersonSex) {    ZLPersonSexMale = 0,    ZLPersonSexFamale};@interface ZLPersonModel : NSObject/** NSString 姓名 */@property (nonatomic, copy) NSString *name;/** NSUInteger 年龄 */@property (nonatomic, assign, readonly) NSUInteger age;/** ZLPersonSex 性别 */@property (nonatomic, assign, readonly) ZLPersonSex sex; (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex;@endZLPersonModel.m#import "ZLPersonModel.h"@implementation ZLPersonModel- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex{    if (self = [super init]) {        _name = name;        _age = age;        _sex = sex;    }    return self;} (instancetype)personWithName:(NSString *)name age:(NSUInteger)age sex:(ZLPersonSex)sex{    return [[self alloc] initWithName:name age:age sex:sex];}- (NSString *)description{    return [NSString stringWithFormat:@"[name = %@, age = %ld, sex = %ld]", self.name, self.age, self.sex];}@end上边让我们进来正题例一:(最简便易行的利用)ZLPersonModel *sunnyzl = [ZLPersonModel personWithName:@"sunnyzl" age:29 sex:ZLPersonSexMale];    ZLPersonModel *jack = [ZLPersonModel personWithName:@"jack" age:22 sex:ZLPersonSexMale];    //  首先我们来看有些简短的行使    //  1.判别姓名是不是是以s开端的    NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"name LIKE 's*'"];    //  输出为:sunnyzl:1, jack:0    NSLog(@"sunnyzl:%d, jack:%d", [pred1 evaluateWithObject:sunnyzl], [pred1 evaluateWithObject:jack]);    //  2.判断年龄是不是抢先25    NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"age > 25"];    //  输出为:sunnyzl的岁数是还是不是高于25:1, jack的年华是还是不是超过25:0    NSLog(@"sunnyzl的年纪是不是高出25:%d, jack的年纪是不是超越25:%d", [pred2 evaluateWithObject:sunnyzl], [pred2 evaluateWithObject:jack]);看到这里大家会意识evaluateWithObject:方法重回的是二个BOOL值,假使符合条件就回到YES,不合乎就回到NO。而即就是最简便的运用也许有部分大用处,比如原先大家写剖断手提式无线电话机号码、邮政编码等等,像笔者就欣赏用JohnEngelhart大神的RegexKitLite,不过由于绵绵须求导入libicucore.dylib库(xcode7为libicucore.tbd)且由于是mrc又供给增多-fno-objc-arc,至此大家技艺利用。然则使用谓词让我们得以用平等简洁的代码完成平等的效果与利益例二:(判定手机号是或不是科学)

@property (nonatomic, strong) NSArray *filter;

NSPredicate

  • (BOOL)checkPhoneNumber:(NSString *)phoneNumber{    NSString *regex = @"^[1][3-8]\d{9}$";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];    return [pred evaluateWithObject:phoneNumber];}看到此间是还是不是感觉好爽,感到从前全数的正则都能够那样相配,不过谓词相称正则时也可能有劣势的,下边通过多少个例证来看一下以此沉重的短处例三:谓词匹配正则的毛病(本意:检查测验字符串中是或不是有特殊字符)- (BOOL)checkSpecialCharacter:(NSString *)string{    NSString *regex = @"[`~!@#$^&*()=|{}':;',\[\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];    return [pred evaluateWithObject:string];}大家想要的魔法是字符串中有特殊字符时就回来YES,不过梦想是美好的,现实是残暴的让我们看看那悲催的结果NSString *testString = @"!";NSLog(@"是不是包蕴特殊字符:%d", [self checkSpecialCharacter:testString]);//  当testString为一个特殊字符时,大家欢畅的意识输出为//  是还是不是含有特殊字符:1观看这里大家内心蓦然一喜,那tmd根本没难题嘛让我们修改下testString的值NSString *testString = @"!~";NSLog(@"%d", [self checkSpecialCharacter:testString]);//  大家会意识悲催的结局来了出口为//  是不是饱含特殊字符:0再度修改testString的值NSString *testString = @"abc!~d";NSLog(@"%d", [self checkSpecialCharacter:testString]);//  大家会发掘输出为//  是还是不是带有特殊字符:0那总与大家的主见救经引足,看到此间大家会发觉谓词对正则并不像大家运用NSRegularExpression时万分的那么好,究其原因是怎么吧?我们用NSRegularExpression时会开采匹配到八个结果时就能够存入数组,再从相配到的地方两次三番向下匹配。但是NSPredicate并不会做如此的全自动操作,大家最终发掘在NSPredicate输入[`~!@#$^&*()=|{}':;',[].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]正则表达式时和写成^[`~!@#$^&*()=|{}':;',[].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]$的功力是同样的。所以通过那一个事例我们总计出来,唯有在正则表明式为^表明式$时才使用谓词,并不是兼备情形都选用。当然上例中大家得以用二个投机取巧的措施达成(然则仅能用来相称是不是含有特殊符号,而不能像NSRegularExpression这样对那一个特殊符号实行理并答复杂操作)大家得以将- (BOOL)checkSpecialCharacter:(NSString *)string更改为:- (BOOL)checkSpecialCharacter:(NSString *)string{    NSString *regex = @".*[`~!@#$^&*()=|{}':;',\[\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?].*";    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];    return [pred evaluateWithObject:string];}其实上述格局也只是极其了二遍,只然则大家将它的范围扩充了。那么我们是否因为那点就扬弃它了啊,答案是不是定的。因为即使NSPredicate有这么一点劣势,不过它完整带给我们的福利其实不外乎正则表明式相配时的那几个难题外是更加多的。2.行使谓词过滤会集此部分是我们须求调控的要害,因为从这里我们就足以看出谓词的真的的壮大之处其实谓词本人就代表了二个逻辑条件,计算谓词之后回来的结果长久为BOOL类型的值。而谓词最常用的效果就是对聚焦进行过滤。当程序行使谓词对会集成分进行过滤时,程序会自行遍历其成分,并基于集合成分来测算谓词的值,当那个集结中的成分总括谓词并赶回YES时,那个成分才会被封存下去。请留意程序会自行遍历其元素,它会将电动遍历过之后重回为YES的值重新组合成八个会面重回。其实看似于大家采纳tableView设置索引时使用的下段代码- (NSArray*)sectionIndexTitlesForTableView:(UITableView *)tableView{    return [self.cityGroup valueForKey:@"title"];}中的[self.cityGroup valueForKey:@"title"]。它的效力是遍历全体title并将获得的值组成新的数组。NSArray提供了如下方法应用谓词来过滤集结- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate:使用钦定的谓词过滤NSArray集结,重返符合条件的要素结合的新集合NSMutableArray提供了如下方法运用谓词来过滤群集- (void)filterUsingPredicate:(NSPredicate *)predicate:使用钦命的谓词过滤NSMutableArray,剔除群集中不符合条件的元素NSSet提供了之类方法运用谓词来过滤集结- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):功用同NSArray中的方法

示例:数组{@"type:酒店", @"star:[3,5]"}的含义,等同于SQL语句:WHERE type = "酒店" AND star BETWEEN 3 AND 5

Cocoa提供了三个NSPredicate类,它用来内定过滤器的条件

NSMutableSet提供了如下方法应用谓词来过滤集结

1):三遍呼吁只可以获得100条数据,不能够贰遍把当下数码筛选完;

/// 可选, 每页记录数(每页最大记录数100, 暗许20)

@property (nonatomic, assign) NSInteger offset;

/// 可选, 当前页数(>=1, 私下认可1)

@property (nonatomic, assign) NSInteger page;

竭泽而渔方案:

上一页有100条,而且没筛选到30条就再获得下一页数据;

筛选出来30条,恐怕云图筛选完结就去地图突显数据;

最早化方法

- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):成效同NSMutableArray中的方法。

2):先从云图获取数据再扩充最多各类规格的筛选

NSMutableArray *foods = [@[] mutableCopy];for(Food *foodinself.sources) {if([food.nameisEqualToString:@"呵呵"]) {

[arrayMaddObject:food];

}

}

//做二个筛选 - 筛选完也许筛选了二十九个结实后显得出来

//四筛一

//四筛二

//四筛三

//四筛四

这种做法在要筛选两种口径的情事下将会极其低效,何况复杂,景况比非常多;

NSPredicate类是用来定义逻辑条件约束的收获或内部存储器中的过滤找寻。

可以运用谓词来表示逻辑条件,用于描述对象长久性存款和储蓄在内部存储器中的对象过滤。其实意思就是:小编是贰个过滤器,不符合条件的都滚开。

NSPredicate的主导语法

大家选择一门语言,无论是外语依然Computer语言,总是从语法开头的,那样我们技巧科学的握住逻辑。所以大家从语法初始谈起。在那有个别大家仅关心其语法的应用

假诺我们应用谓词(NSPredicate)都亟需为谓词定义谓词表明式,而这一个表明式必得是二个回去BOOL的值。

谓词表明式由表明式、运算符和值构成。

-filterFourConditonWihtPois:(NSArray *)pois{

[self.predicateArr removeAllObjects];

if (self.typeArr.count) {

//address customFields

NSPredicate * p1 = [NSPredicate predicateWithFormat:@"type in %@", self.typeArr];//SELF

[self.predicateArr addObject:p1];

}

if (self.gradeArr.count) {

NSPredicate * p2 = [NSPredicate predicateWithFormat:@"grade in %@", self.gradeArr];

[self.predicateArr addObject:p2];

}

if (self.is_publicArr.count) {

NSPredicate * p3 = [NSPredicate predicateWithFormat:@"is_public in %@", self.is_publicArr];

[self.predicateArr addObject:p3];

}

if (self.disArr.count) {

NSPredicate * p4 = [NSPredicate predicateWithFormat:@"dis_id in %@", self.disArr];

[self.predicateArr addObject:p4];

}

if (self.predicateArr.count) {

// NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:self.predicateArr];

NSPredicate * predicate = [NSCompoundPredicate andPredicateWithSubpredicates:self.predicateArr];

NSInteger count = 0;

for (AMapCloudPOI *aPOI in pois) {

BOOL match = [predicate evaluateWithObject:aPOI.customFields];

NSLog (@"%s", ? "YES" : "NO");//看到此间大家会意识evaluateWithObject:方法重临的是一个BOOL值,假设符合条件就回去YES,不吻合就回去NO。

if {

[self.selectedPoiArray addObject:aPOI];

count ;

if (count == 30) {

break;

}

}

}

//上一页有100条,並且没筛选到30条就再获得下一页数据

if (self.dataCount == 100 && count < 30) {

self.page ;

[self cloudPlacePolygonSearch];

}else{//筛选出来30条,大概云图筛选达成就去地图彰显数据

if (count == 0) {

[self.view makeToast:@"未筛选到多少"];

}

[self addAnnotionsWithPOIs:self.selectedPoiArray];

}

}else{

[self addAnnotionsWithPOIs:pois];

}

}

NSPredicate * predicate = [NSPredicate predicateWithFormat:@"is_public in %@", self.is_publicArr];

筛选语句里面包车型地铁数字不能够为字符串类型,要转变到数字类型,不然不能够筛选成功;

for (NSString * str in arr[0]) {

if ([str isEqualToString:@"公办"]) {

NSNumber * number =[NSNumber numberWithInt:1];

[self.is_publicArr addObject:number];

}else if ([str isEqualToString:@"私立"]){

NSNumber * number =[NSNumber numberWithInt:0];

[self.is_publicArr addObject:number];

}

}

 (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;

透过下面的陈述能够见见,使用谓词过滤不可变集结和可变群集的区分是:过滤不可变集合时,会重返符合条件的集合成分组成的新集结;过滤可变群集时,未有再次回到值,会直接删除不符合条件的会集成分

Format:

下边让大家来看多少个例子:

/**
 1.格式表达符
 %d和%@等插入数值和字符串,%K表示key
 还是能够引进变量名,用$,类似意况变量,如:@"name == $NAME",再用predicateWithSubstitutionVariables调用来组织新的谓词(键/值字典),其中键是变量名,值是要插入的内容,注意这种处境下不可能把变量当成键路线,只可以用作值
 2.运算符
 
 ==等于
 
 >:大于
 
 >=和=>:大于或等于
 
 <:小于
 
 <=和=<:小于或等于
 
 !=和<>:不等于
 
 括号和逻辑运算AND、O奥迪Q5、NOT大概C样式的等效表明式&&、||、!
 
 注意:不等号适用于数字和字符串
 
 
 3. 数组运算符
 BETWEEN和IN后加有个别数组,能够用{50,200},也得以用%@格式表明符插入本身的靶子,也足以用变量
 
 4.SELF足够了
 self就表示对象自己
 
 5.字符串运算符
 BEGINSWITH:以某些字符串最初
 
 ENDSWITH:以有个别字符串甘休
 
 CONTAINS:包罗有些字符串
 @"name ENDSWITH[d] 'ang'"
 
 [c],[d],[cd],后缀表示不区分轻重缓急写,不区分发音符号,两以此都不区分

例一:

 6.LIKE运算符
 
 类似SQL的LIKES
 
 LIKE,与通配符“*”表示狂妄多和“?”表示一个组成使用
 
 LIKE也接受[cd]符号
 
 7.MATCHES能够运用正则表明式
 NSString *regex = @"^A. e$";   //以A开头,e结尾
 */

NSMutableArray *arrayM = [@[@20, @40, @50, @30, @60, @70] mutableCopy];

 

//  过滤大于50的值

数组的类目:用来过滤数组

NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF > 50"];

- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 

[arrayM filterUsingPredicate:pred1];

 可变数组能够一贯过滤

NSLog(@"arrayM:%@", arrayM);

- (void)filterUsingPredicate:(NSPredicate *)predicate; 

NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale],

 例:过滤出数组中的字符串中隐含ang的要素

[ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],

    NSArray *array = [[NSArray alloc]initWithObjects:@"beijing",@"shanghai",@"guangzou",@"wuhan", nil];
    NSString *string = @"ang";
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS %@",string];
    NSLog(@"%@",[array filteredArrayUsingPredicate:pred]);

[ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],

 单个对象的过滤

[ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];

- (BOOL)evaluateWithObject:(id)object;

//  须要抽取包含‘son’的因素

 例:判别字符串中首字母是或不是字母

NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"name CONTAINS 'son'"];

  NSString *regex = @"[A-Za-z] ";
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    
    if ([predicate evaluateWithObject:@"hahaa"]) {
        NSLog(@"首字母含有字母");
    }else {
        NSLog(@"首字母不含字母");
    }

NSArray *newArray = [array filteredArrayUsingPredicate:pred2];

过滤语句:邮箱过滤@"[A-Z0-9a-z._% -] @[A-Za-z0-9.-] \.[A-Za-z]{1,5}";

NSLog(@"%@", newArray);

电话号码部分:@"^1(3[0-9]|5[0-35-9]|8[025-9])\d{8}$"

输出为

NSRegularExpression

2016-01-07 16:50:09.510 PredicteDemo[13660:293822] arrayM:(

字符串替换

60,

 NSError* error = NULL;
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"(encoding=")[^"] (")"
                                                                           options:0
                                                                             error:&error];
    NSString* sample = @"<xml encoding="abc"></xml><xml encoding="def"></xml><xml encoding="ttt"></xml>";
    NSLog(@"Start:%@",sample);
    NSString* result = [regex stringByReplacingMatchesInString:sample
                                                       options:0
                                                         range:NSMakeRange(0, sample.length)
                                                  withTemplate:@"$1utf-8$2"];
    NSLog(@"Result:%@", result);

70

字符串中截取字符串

)

   //组装贰个字符串,供给把在那之中的网站剖析出来
    NSString *urlString=@"<meta/><link/><title>1Q84 BOOK1</title></head><body>";
    
    //NSRegularExpression类里面调用表明的主意要求传递二个NSError的参数。上边定义叁个
    NSError *error;
    
    //http :[^\s]* 这一个表达式是检查实验三个网站的。(?<=title>).*(?=</title)截取html小说中的<title></title>中内文字的正则表明式
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=title\>).*(?=</title)" options:0 error:&error];
    
    if (regex != nil) {
        NSTextCheckingResult *firstMatch=[regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];
        
        if (firstMatch) {
            NSRange resultRange = [firstMatch rangeAtIndex:0];
            
            //从urlString当中截取数据
            NSString *result=[urlString substringWithRange:resultRange];
            //输出结果
            NSLog(@"->%@<-",result);
        }
    }

2016-01-07 16:50:09.511 PredicteDemo[13660:293822] (

 NSPredicate测试:

"[name = Jackson, age = 30, sex = 0]",

里头自定义三个类,出事的时候给属性赋值,用runtime获取具有属性同仁一视写description方法

"[name = Johnson, age = 35, sex = 0]"

@interface DataModel : NSObject

)

@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger num;

从这一个例子我们就足以见到NSPredicate有多么强大,假若让大家用别样的章程来兑现又是一大堆if...else。

@end

让我们来回看一下地点的从第四个数组中去除第二个数组中同样的要素

#import "DataModel.h"
#import <objc/runtime.h>

例二:

@implementation DataModel

NSArray *filterArray = @[@"ab", @"abc"];

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.name = @"haha";
        self.num = 12;
    }
    return self;
}

NSArray *array = @[@"a", @"ab", @"abc", @"abcd"];

//修改描述文件(获取具备属性存成字典)
- (NSString *)description {
    u_int               count;
    objc_property_t*    properties= class_copyPropertyList([self class], &count);
    NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
    for (int i = 0; i < count ; i )
    {
        const char* propertyName = property_getName(properties[i]);
        NSString *strName = [NSString  stringWithCString:propertyName encoding:NSUTF8StringEncoding];
        [dic setObject:[self valueForKey:strName] forKey:strName];
    }
    return [NSString stringWithFormat:@"<%@ %p>:%@",self.class,&self,dic];
}

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT (SELF IN %@)", filterArray];

 例子:

NSLog(@"%@", [array filteredArrayUsingPredicate:predicate]);

//(1)比较运算符>,<,==,>=,<=,!=
- (void)test1 {
    DataModel *model = [[DataModel alloc]init];
    //类里面
    /*
     self.name = @"haha";
     self.num = 12;
     */
    //可剖断三个类的贰个天性是还是不是等于有个别值,字符串是还是不是等于
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num > 11"];
    BOOL match = [predicate evaluateWithObject:model];
    NSLog(@"%@",match?@"yes":@"no");
}

输出为:

//强悍的数组过滤效果
- (void)test2 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2 = [[DataModel alloc]init];
    DataModel *model3 = [[DataModel alloc]init];
    model2.num = 8;
    model3.name = @"lala";
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num > 10 AND name == 'lala'"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog(@"过滤出了: %@",mutableArray);
}

2016-01-07 13:17:43.669 PredicteDemo[6701:136206] (

//含有变量的谓词,在那边用><会崩溃
- (void)test3 {
    DataModel *model= [[DataModel alloc]init];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name == $key"];
    NSDictionary *dic = @{@"key":@"haha"};
    NSPredicate *predicate1 = [predicate predicateWithSubstitutionVariables:dic];
    NSLog(@"%@",predicate1);
    BOOL match = [predicate1 evaluateWithObject:model];
    NSLog(@"%@",match?@"yes":@"no");
}

a,

//BETWEEN
//BETWEEN和IN后加某些数组,能够用{50,200},也得以用%@格式表明符插入本身的目的,也足以用变量
- (void)test4 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2 = [[DataModel alloc]init];
    DataModel *model3 = [[DataModel alloc]init];
    model2.num = 8;
    model3.num = 20;
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"num BETWEEN {5,15}"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog(@"过滤出了: %@",mutableArray);
}

abcd

//IN运算符

)

- (void)test5 {
    
    NSArray *arrayFilter = [NSArray arrayWithObjects:@"abc1", @"abc2", nil];
    
    NSMutableArray *arrayContent = [NSMutableArray arrayWithObjects:@"a1", @"abc1", @"abc4", @"abc2", nil];
    
    //过滤出arrayContent 不包含 arrayFilter的元素
    NSPredicate *thePredicate = [NSPredicate predicateWithFormat:@"NOT (SELF in %@)", arrayFilter];
    
    [arrayContent filterUsingPredicate:thePredicate];
    NSLog(@"%@",arrayContent);
}

若果我们不要NSPredicate的话,料定又是种种if...else,for循环等等。能够观望NSPredicate的产出为大家节省了汪洋的时日和活力。

//BEGINSWITH,ENDSWITH,CONTAINS
//LIKE运算符(通配符)
- (void)test6 {
    NSMutableArray *mutableArray = [[NSMutableArray alloc]init];
    DataModel *model1= [[DataModel alloc]init];
    DataModel *model2= [[DataModel alloc]init];
    DataModel *model3= [[DataModel alloc]init];
    model1.name = @"a123.png";
    model3.name = @"a.png";
    [mutableArray addObject:model1];
    [mutableArray addObject:model2];
    [mutableArray addObject:model3];
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"name LIKE[cd] 'a*.png'"];
    [mutableArray filterUsingPredicate:predicate];
    NSLog (@"%@", mutableArray);
}

3.在谓词中运用占位符参数

 

咱俩地方装有的事例中谓词总是恒久的,但是大家在现实中处理变量时间调整制了谓词应该是可变的。上边大家来看看要是让谓词变化起来。

第一若是大家想在谓词表明式中接纳变量,那么大家要求领会下列三种占位符

%K:用于动态传入属性名

%@:用于动态设置属性值

事实上一定于变量名与变量值

而外,仍是能够在谓词表达式中接纳动态退换的属性值,仿佛意况变量同样

NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF CONTAINS $VALUE"];

上述表明式中,$VALUE是三个能够动态变化的值,它其实提起底是在字典中的多少个key,所以能够遵照你的内需写不相同的值,然而必得有$初始,随着程序更改$VALUE这几个谓词表明式的相比标准就足以动态退换。

上面我们经过三个事例来走访那五个首要的占位符应该怎样运用

例一:

NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale],

[ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],

[ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],

[ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];

//  定义一个property来寄放在属性名,定义五个value来存放值

NSString *property = @"name";

NSString *value = @"Jack";

//  该谓词的成效是固然成分中property属性含有值value时就抽取归入新的数组内,这里是name满含杰克

NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", property, value];

NSArray *newArray = [array filteredArrayUsingPredicate:pred];

NSLog(@"newArray:%@", newArray);

//  创造谓词,属性名改为age,供给那几个age满含$VALUE字符串

NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];

// 指定$VALUE的值为 25

NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}];

NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];

NSLog(@"newArray1:%@", newArray1);

//  修改 $VALUE的值为32

NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}];

NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];

NSLog(@"newArray2:%@", newArray2);

输出为

2016-01-07 17:28:02.062 PredicteDemo[14542:309494] newArray:(

"[name = Jack, age = 20, sex = 0]",

"[name = Jackson, age = 30, sex = 0]"

)

2016-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray1:(

"[name = Jackson, age = 30, sex = 0]",

"[name = Johnson, age = 35, sex = 0]"

)

2016-01-07 17:28:02.063 PredicteDemo[14542:309494] newArray2:(

"[name = Johnson, age = 35, sex = 0]"

)

本文由pc28.am发布于计算机编程,转载请注明出处:谓词的主干使用,iOS中的过滤器和正则表达式

上一篇:启动图片尺寸 下一篇:没有了
猜你喜欢
热门排行
精彩图文