NSPredicate 的使用

NSPredicate 这个类主要有两个方面的作用:

  1. 从集合类中过滤数据
  2. 和正则表达式进行正则判断(比方说验证手机号,邮箱,IP地址是否满足要求,其实还是过滤数据)

集合中过滤数据

@interface Person : NSObject
@property NSString *firstName;
@property NSString *lastName;
@property NSNumber *age;
@end

@implementation Person

- (NSString *)description {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

@end

#pragma mark -

NSArray *firstNames = @[ @"Alice", @"Bob", @"Charlie", @"Quentin" ];
NSArray *lastNames = @[ @"Smith", @"Jones", @"Smith", @"Alberts" ];
NSArray *ages = @[ @24, @27, @33, @31 ];

NSMutableArray *people = [NSMutableArray array];
[firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    Person *person = [[Person alloc] init];
    person.firstName = firstNames[idx];
    person.lastName = lastNames[idx];
    person.age = ages[idx];
    [people addObject:person];
}]; 
  1. 过滤对象的firstName属性 firstName = 'Bob',执行结果是获取 firstName = 'Bob' 的数组
NSPredicate *bobPredicate = [NSPredicate predicateWithFormat:@"firstName = 'Bob'"];
NSLog(@"Bobs: %@", [people filteredArrayUsingPredicate:bobPredicate]);
["Bob Jones"]
  1. 过滤对象 age >= 30
NSPredicate *thirtiesPredicate = [NSPredicate predicateWithFormat:@"age >= 30"];
NSLog(@"30's: %@", [people filteredArrayUsingPredicate:thirtiesPredicate]);
["Charlie Smith", "Quentin Alberts"]
  1. 过滤年龄 在 26和30之间的情况
 NSPredicate *agePredicate2 = [NSPredicate predicateWithFormat:@"age BETWEEN {26, 30}"];
 NSLog(@"age2:%@",[people filteredArrayUsingPredicate:agePredicate2]);
    
  1. 过滤年龄在 26 到30 之间,firstName为 'Alice','Bob' 的情况
 NSPredicate *agePredicate4 = [NSPredicate predicateWithFormat:@"SELF.firstName IN {'Alice','Bob'} && SELF.age BETWEEN {26,30} "];
  NSLog(@"age4:%@",[people filteredArrayUsingPredicate:agePredicate4]);

5.过滤firstName 为alice(忽略大小写和重低音的情况)

 NSPredicate *agePredicate5 = [NSPredicate predicateWithFormat:@"firstName LIKE[cd] 'alice'"];
 NSLog(@"agePredicate5:%@",[people filteredArrayUsingPredicate:agePredicate5]);

一些谓词

基本比较

=, ==:左边的表达式和右边的表达式相等。(谓词中 = 和 == 一样的,都是比较,没有赋值的意思)
=, =>:左边的表达式大于或者等于右边的表达式。
<=, =<:左边的表达式小于等于右边的表达式。

:左边的表达式大于右边的表达式。
<:左边的表达式小于右边的表达式。
!=, <>:左边的表达式不等于右边的表达式。
BETWEEN:左边的表达式等于右边的表达式的值或者介于它们之间。右边是一个有两个指定上限和下限的数值的数列(指定顺序的数列)。比如,1 BETWEEN { 0 , 33 },或者LOWER, $UPPER }。

基本符合谓词

  • AND, &&:逻辑与.
  • OR, ||:逻辑或.
  • NOT, !:逻辑非.

字符串比较

字符串比较在默认的情况下是区分大小写和音调的。你可以在方括号中用关键字符c和d来修改操作符以相应的指定不区分大小写和变音符号,比如firstname BEGINSWITH[cd] $FIRST_NAME。

BEGINSWITH:左边的表达式以右边的表达式作为开始。
CONTAINS:左边的表达式包含右边的表达式。
ENDSWITH:左边的表达式以右边的表达式作为结束。
LIKE:左边的表达式等于右边的表达式:?和可作为通配符,其中?匹配1个字符,匹配0个或者多个字符。
MATCHES:左边的表达式根据ICU v3(更多内容请查看ICU User Guide for Regular Expressions)的regex风格比较,等于右边的表达式。

合计操作

关系操作

ANY,SOME:指定下列表达式中的任意元素。比如,ANY children.age < 18。(特别要注意的是操作对象必须是集合,比方说数组套数组的情况,操作对象就是数组) 集合中任意一个元素满足条件,就返回YES

ALL:指定下列表达式中的所有元素。比如,ALL children.age < 18。 集合中所有元素都满足条件,才返回YES

NONE:指定下列表达式中没有的元素。比如,NONE children.age < 18。它在逻辑上等于NOT (ANY ...)。 集合中没有任何元素满足条件就返回YES。

IN:等于SQL的IN操作,左边的表达必须出现在右边指定的集合中。比如,name IN { 'Ben', 'Melissa', 'Nick' } 等价于SQL语句中的IN运算符,只有当左边表达式或值出现在右边的集合中才会返回YES

数组操作

array[index]:指定数组中特定索引处的元素。
array[FIRST]:指定数组中的第一个元素。
array[LAST]:指定数组中的最后一个元素。
array[SIZE]:指定数组的大小。

布尔值谓词

TRUEPREDICATE:结果始终为真的谓词。
FALSEPREDICATE:结果始终为假的谓词。

直接量

在谓词表达式中可以使用如下直接量

FALSE、NO:代表逻辑假
TRUE、YES:代表逻辑真
NULL、NIL:代表空值
SELF:代表正在被判断的对象自身
"string"或'string':代表字符串
数组:和c中的写法相同,如:{'one', 'two', 'three'}。
数值:包括证书、小数和科学计数法表示的形式
十六进制数:0x开头的数字
八进制:0o开头的数字
二进制:0b开头的数字
3.6.保留字

下列单词都是保留字(不论大小写)
AND、OR、IN、NOT、ALL、ANY、SOME、NONE、LIKE、CASEINSENSITIVE、CI、MATCHES、CONTAINS、BEGINSWITH、ENDSWITH、BETWEEN、NULL、NIL、SELF、TRUE、YES、FALSE、NO、FIRST、LAST、SIZE、ANYKEY、SUBQUERY、CAST、TRUEPREDICATE、FALSEPREDICATE
注:虽然大小写都可以,但是更推荐使用大写来表示这些保留字

SELF 指的就是要被判断的谓词对象。

过滤方面的具体使用

例子1:获取选中的规格ID

isSelected

- (NSString *)SpecValIds {
   // 创建谓词对象
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"isSelected == %d",YES];
   //self.platProductAttributeAndSpecificationDto.ProductSpecificationDtos 为一个数组
    NSMutableArray *tmparr = [self.platProductAttributeAndSpecificationDto.ProductSpecificationDtos filteredArrayUsingPredicate:predicate];
    // 从数组中拿到对象,对这个对象的id进行去重,并且把 id 放到一个数组中进行返回
    NSArray *editReturnedModeltmparr = [tmparr valueForKeyPath:@"@distinctUnionOfObjects.id"];//
   //  NSString iOS 将数组中的元素用符号拼接字符串的方法
    NSString *string = [editReturnedModeltmparr componentsJoinedByString:@","];
    return string;
}

例子2:数据的过滤,城市搜索

一般的城市搜索,都是支持字母拼写和汉字搜索的。
可以使用谓词,也可以不使用谓词。

方式一,不使用谓词

+ (NSArray *)searchcityModelsWithSeatchText:(NSString *)searchText{
    NSMutableArray *array = [NSMutableArray array];
    //拼音转化为大写
    searchText = [searchText uppercaseString];
    for (DKCityModel *obj in _cityModels) {
        if ([obj.name.uppercaseString containsString:searchText] || [obj.pinYin.uppercaseString containsString:searchText] || [obj.pinYinHead.uppercaseString containsString:searchText]) {
            [array addObject:obj];
        }
    }
    return array;
}

方式二 :使用谓词

searchText  = searchText.uppercaseString;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@" pinYinHead.uppercaseString  contains %@ or  name.uppercaseString  contains %@  or pinYin.uppercaseString  contains %@ ",searchText,searchText,searchText];
 return [_cityModels filteredArrayUsingPredicate:predicate];

很明显使用谓词代码量更少,代码更简单。

正则表达式进行判断

利用NSPredicate 的evaluateWithObject 方法进行正则匹配。

#pragma 正则匹配手机号
+ (BOOL)checkTelNumber:(NSString *) telNumber {
    NSString *pattern = @^1+[3578]+\d{9};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:telNumber];
    return isMatch;
}
  
  
#pragma 正则匹配用户密码6-18位数字和字母组合
+ (BOOL)checkPassword:(NSString *) password {
    NSString *pattern = @^(?![0-9]+$)(?![a-zA-Z]+$)[a-zA-Z0-9]{6,18};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:password];
    return isMatch;
      
}
  
#pragma 正则匹配用户姓名,20位的中文或英文
+ (BOOL)checkUserName : (NSString *) userName {
    NSString *pattern = @^[a-zA-Z一-龥]{1,20};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:userName];
    return isMatch;  
}
  
  
#pragma 正则匹配用户身份证号15或18位
+ (BOOL)checkUserIdCard: (NSString *) idCard{
    NSString *pattern = @(^[0-9]{15}$)|([0-9]{17}([0-9]|X)$);
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:idCard];
    return isMatch;
}
  
#pragma 正则匹员工号,12位的数字
+ (BOOL)checkEmployeeNumber : (NSString *) number{
    NSString *pattern = @^[0-9]{12}; 
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:number];
    return isMatch;
      
}
  
#pragma 正则匹配URL
+ (BOOL)checkURL : (NSString *) url{
    NSString *pattern = @^[0-9A-Za-z]{1,50};
    NSPredicate *pred = [NSPredicate predicateWithFormat:@SELF MATCHES %@, pattern];
    BOOL isMatch = [pred evaluateWithObject:url];
    return isMatch;
}

你可能感兴趣的:(NSPredicate 的使用)