Predicate

本文介绍了在Cocoa中如何利用Predicates进行高效的数据查询与过滤。包括基本的查询格式设置,通过Predicate进行数据筛选的方法,并提供了多个示例,如过滤特定范围的数据、匹配数组中的元素、处理空值及使用正则表达式等。

Predicates

Predicates provide a general means of specifying queries in Cocoa. The predicate system is capable of handling a large number of domains, including Core Data and Spotlight.

苹果官方的描述Predicates是在Cocoa中的一种查询格式,可以用于大量数据时候的查询操作,包含Core Data和 Spotlight中;

通过我们过滤数据的方式是通过一个循环,在循环中建立过滤条件,然后对过滤的数据进行操作,或者增加到一个新的容器当中,例如新建一个Array; 在iOS中有一种更加优雅的方式来实现,通过Predicate,建立一个模式,然后对数据进行模式匹配,筛选出符合条件的数据。

demo地址:下载

过滤中间数据

- (void)predicateWithBetween {
  //1
    NSPredicate *betweenPredicate = [NSPredicate predicateWithFormat:@"attributeName BETWEEN %@",@[@1,@10]];
    NSDictionary *dictionary = @{@"attributeName":@5};
  // 2
    BOOL between = [betweenPredicate evaluateWithObject:dictionary];
    if (between) {
        NSLog(@"between");
    }
}

1.建立正则表达式,表示数据的范围是[1-10],并且定义一个字典

2.对该字典执行Predicate匹配,between用来接收匹配的结果

匹配数组中的数据

- (void)evaluationAPredicate {
  // 1
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@",@[@"Stig",@"Shaffiq",@"Chris"]];
    BOOL result = [predicate evaluateWithObject:@"Shaffiq"];
  // 2
    // object must support key-value coding
    if (result) {
        NSLog(@"evaluate predicate success");
    }
}

1.建立predicate,筛选出是否包含该字符串集合;

2.对字符串进行匹配,要求匹配对象必须满足kvc;

过滤数据中的数据

- (void)predicateWithArrays {
    NSMutableArray *names = [@[@"Nick",@"Ben",@"Adam",@"Melissa"] mutableCopy];
  // 1
    NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'b'"];
    NSArray *beginWithB = [names filteredArrayUsingPredicate:bPredicate];
    NSLog(@"beginWithB:%@",beginWithB);
    // 2
    NSPredicate *ePredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] 'e'"];
    NSArray *containsE = [names filteredArrayUsingPredicate:ePredicate];
    NSLog(@"contains e:%@",containsE);
    
}

1.过滤数组中以 “b” 开头的字符;

2.过滤数组中包含“e”的字符串

过滤数组中的空数据

- (void)predicateWithNullValue {
    NSString *firstName = @"Ben";
//    NSArray *array = @[@{@"lastName":@"Turner"}];
//    @{@"firstName":@"Ben",@"lastName":@"Ballard",@"birthday":[NSDate dateWithString:@"1972-03-24 10:45:32 +0600"]};
    NSArray *array = @[ @{@"lastName":@"Turner"},
                        @{ @"firstName" : @"Ben",
                           @"lastName"  : @"Ballard",
                           @"birthday"  : [NSDate dateWithString:@"1972-03-24 10:45:32 +0600"] } ];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstName like %@",firstName];
    NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
    NSLog(@"filtered Array:%@",filteredArray);
    
    // using greater than method
    NSDate *referenceDate = [NSDate dateWithTimeIntervalSince1970:0];
  // 1 
    predicate = [NSPredicate predicateWithFormat:@"birthday > %@",referenceDate];
    filteredArray = [array filteredArrayUsingPredicate:predicate];
    NSLog(@"filtered2 Array:%@",filteredArray);
    
   //  test for null value
  // 2
    predicate = [NSPredicate predicateWithFormat:@"(firstName == %@) || (firstName = nil)",firstName];
    filteredArray = [array filteredArrayUsingPredicate:predicate];
    NSLog(@"filtered3 Array:%@",filteredArray);
    // test null result ok
  // 3
    predicate = [NSPredicate predicateWithFormat:@"firstName = nil"];
    BOOL ok = [predicate evaluateWithObject:[NSDictionary dictionary]];
    // 打印的格式控制符号https://blog.youkuaiyun.com/liangliang2727/article/details/40652557
    NSLog(@"ok 1:%hhd",ok);
  // 4
    ok = [predicate evaluateWithObject:[NSDictionary dictionaryWithObject:[NSNull null] forKey:@"firstName"]];
    NSLog(@"ok 2:%hhd",ok);
}
  1. 过滤birthday在referenceDate之后的日期的数据;
  2. 过滤数组中firstName为空的数据;
  3. 过滤空字典中键值firstName为空的数据;
  4. 过滤字典中firstName对应的Value为[NSNull null]的数据

通过正则表达式过滤


- (void)predicateWithRegularExpressions {
    NSArray *array = @[@"TATACCATGGGCCATCATCATCATCATCATCATCATCATCATCACAG",
                       @"CGGGATCCCTATCAAGGCACCTCTTCG", @"CATGCCATGGATACCAACGAGTCCGAAC",
                       @"CAT", @"CATCATCATGTCT", @"DOG"];

    //'.*(CAT){3,}(?!CA).*'
    NSPredicate *catPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '.*(CAT){3,}(?!CA).*'"];
    NSArray *filteredArray = [array filteredArrayUsingPredicate:catPredicate];
    NSLog(@"filetered Array :%@",filteredArray);
    
    // ICU的正则表达方式
    NSArray *isbnTestArray = @[@"123456789X", @"987654321x", @"1234567890", @"12345X", @"1234567890X"];
    NSPredicate *isbnPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES '\\\\d{10}|\\\\d{9}[Xx]'"];
    NSArray *isbnArray = [isbnTestArray filteredArrayUsingPredicate:isbnPredicate];
    NSLog(@"filetered Array :%@",isbnArray);

    
}

 特殊字符组:如匹配任意字母字符,匹配任意字母数字字符,空格或者制表符,0-9,a-z, 任意可打印的字符,标答符号,大写的A-Z;
字符名称描述
^(BRE)脱字符表示在行首页
$美元符定义行尾锚点
.匹配任意单个字符
[]定义一个字符组[ch],其中的字符c和h是或的逻辑,c或者h
[^]字符组取反表示过滤字符组中没有的字符
[0-9]-用来表示数据区间区间也适用于字母如[a-z]; 也可以表示不连续的区间[a-ch-m];
*一次或者多次a*,符号后面放*表示该符号出现一次或者多次;
?(ERE)问号类似于*,b[ae]?t -> bt, 匹配前面的字符出现0次或者一次;
+加号类似于*,匹配一次或者多次,至少出现一次;
{m,n}m,n表示为出现的次数至少出现m次,最多出现n次;
逻辑或处理两种匹配模式
()括号正则表达式的分组

参看资料:

  1. 正则表达式的处理,《linux 命令行与shell脚本编程大全》 428 页, 20章
  2. Apple Predicate官方文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值