【ios开发】关于NSPredicate的详解

NSPredicate是什么?
NSPredicate:谓词,提供了NSPredicate 用于指定过滤条件,谓词是指在计算机中表示计算真假值的函数,它使用起来有点儿像SQL 的查询条件,主要用于从集合中分拣出符合条件的对象,也可以用于字符串的正则匹配。

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
上面只是介绍了谓词的基本内容,下面看实战的实例内容:

//初始化数据
-(void)initDataSource
{
    for (int i = 0; i < 50; i ++) {
        [_dataArray addObject:@{@"name":[NSString stringWithFormat:@"Hello World %d",i],@"age":@"1"}];
    }
}

使用谓词的搜索,在代理方法内

NSArray *tempResults = nil;
    // 谓词搜索
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains [cd] %@ OR age contains [cd] %@",searchText,searchText];
    tempResults =  [_dataArray filteredArrayUsingPredicate:predicate];

    [_resultsData removeAllObjects];
    [_resultsData addObjectsFromArray:tempResults];

@”name contains [cd] %@ OR age contains [cd] %@”,searchText,searchText]这个的意思就是:筛选name的key 的value中包含searchText的字典以及age中包含的searchText的数组,(当然是model类型也是可以的)
这个时候大家应该明白了怎么用了吧!
@”name contains [cd] %@”,searchText] :这个意思name的key的value中包含searchText的内容;

筛选两个数组的不一样的objects

NSArray * arr1 = @[@1,@2,@3];

NSArray * arr2 = @[@2,@3,@4,@5];

NSPredicate * filterPredicate = [NSPredicate predicateWithFormat:@”NOT (SELF IN %@)”,arr1];

NSArray * filter = [arr2 filteredArrayUsingPredicate:filterPredicate];
NSLog(@”%@”,filter);

其他的用法:我就不再一一叙述:参考别人的用法给大家放在这里:

predicate = [NSPredicatepredicateWithFormat:@"name LIKE[cd] '*er*'"];//*代表通配符Like还接受[cd].
results = [cars filteredArrayUsingPredicate: predicate];

NSLog (@"%@", results);




predicate = [NSPredicatepredicateWithFormat:@”name LIKE[cd] ‘???er*’”];//?只匹配一个字符并且还可以接受[cd].

results = [cars filteredArrayUsingPredicate: predicate];

NSLog (@"%@", results);
 NSPredicate *predicate;

    predicate=[NSPredicatepredicateWithFormat:@"name=='Herbie'"];//用predicateWithFormat创建一个谓词,name作为键路径

   BOOL match=[predicateevaluateWithObject:car];//car作为接收对象,evaluateWithObject返回一个bool值。

    NSLog(@"%s",(match)?"YES":"NO");


  predicate = [NSPredicatepredicateWithFormat:@"engine.horsepower > 150"];

    NSArray *cars = [garage cars];

    for (Car *car in [garage cars]) {

        if ([predicate evaluateWithObject: car]) {

            NSLog (@"%@", car.name);

        }

    }
遍历cars判断是否是真,然后输出。

  predicate = [NSPredicatepredicateWithFormat:@"engine.horsepower > 150"];

    NSArray *results;

    results = [carsfilteredArrayUsingPredicate: predicate];//它将循环过滤数组内容,根据谓词计算每个对象的值,并将值为YES的对象累计到将被返回的新数组中。

    NSLog (@"%@", results);
filteredArrayUsingPredicate这个方法可以得到我们所需要的值。加上

   NSArray *names;

    names=[results valueForKey:@"name"];

    NSLog (@"%@", names);
就和上面的值一样。

    NSMutableArray *carsCopy = [carsmutableCopy];

    [carsCopyfilterUsingPredicate: predicate];//filterUsingPredicate和NSMutableArray构成新数组。

    NSLog (@"%@", carsCopy);



    predicate = [NSPredicatepredicateWithFormat:@"engine.horsepower > %d", 50];

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);



    NSPredicate *predicateTemplate;

    NSDictionary *varDict;

    predicateTemplate = [NSPredicatepredicateWithFormat: @"engine.horsepower > $POWER"];//创建一个键/值字典来存储,这里$符号用于变量

    varDict = [NSDictionarydictionaryWithObjectsAndKeys:

               [NSNumbernumberWithInt: 150],@"POWER", nil];//@后面参数名

    predicate = [predicateTemplatepredicateWithSubstitutionVariables: varDict];

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);

  predicate = [NSPredicatepredicateWithFormat:

                @"(engine.horsepower > 50) AND (engine.horsepower < 200)"];//可以运用运算符

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"oop %@", results);



    predicate = [NSPredicatepredicateWithFormat:

                @"engine.horsepower BETWEEN { 50, 200 }"];//这里可以运用between关键字。和上面效果一样

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);



    NSArray *betweens = [NSArray arrayWithObjects:

                         [NSNumbernumberWithInt: 50], [NSNumbernumberWithInt: 200],nil];

    predicate = [NSPredicatepredicateWithFormat: @"engine.horsepower BETWEEN %@", betweens];

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);



    predicateTemplate = [NSPredicatepredicateWithFormat:@"engine.horsepower BETWEEN $POWERS"];

    varDict = [NSDictionarydictionaryWithObjectsAndKeys: betweens, @"POWERS", nil];

    predicate = [predicateTemplatepredicateWithSubstitutionVariables: varDict];//用变量

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);



    predicate = [NSPredicatepredicateWithFormat:@"name < 'Newton'"];//不等号不仅可以用于数字,也可以用于字符串值。

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", [results valueForKey: @"name"]);



    predicate = [NSPredicatepredicateWithFormat:@"name IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];//包含在其中用IN

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", [results valueForKey: @"name"]);



    predicate = [NSPredicatepredicateWithFormat:@"SELF.name IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];//self关键字

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", [results valueForKey: @"name"]);



    names = [cars valueForKey: @"name"];

    predicate = [NSPredicatepredicateWithFormat:@"SELF IN { 'Herbie', 'Snugs', 'Badger', 'Flap' }"];//self关键字

    results = [namesfilteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);



    predicate = [NSPredicatepredicateWithFormat:@"name BEGINSWITH 'Bad'"];//字符串运算符BEGINSWITH,ENDSWITH,CONTAINS[c][d][cd]

    results = [cars filteredArrayUsingPredicate: predicate];

    NSLog (@"%@", results);

    BEGINSWITH:检查某个字符串是否以另一个字符串开头。

    ENDSWITH:检查某个字符串是否以另一个字符串结尾。

    CONTAINS:检查某个字符串是否以另一个字符串内部。

    [c]不区分大小写[d]不区分发音符号即没有重音符号[cd]既不区分大小写,又不区分发音符号。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个使用NSPredicate的Swift代码示例,用于将大量数据按时间分组: ```swift struct DataItem { let name: String let timeStamp: TimeInterval // 时间戳 } func groupDataByTime(_ data: [DataItem]) -> [[DataItem]] { // 将数据按时间先后排序 let sortedData = data.sorted { $0.timeStamp < $1.timeStamp } // 创建空字典 var groups = [String: [DataItem]]() // 使用NSPredicate过滤并分组数据 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" for item in sortedData { let date = Date(timeIntervalSince1970: item.timeStamp) let dateString = dateFormatter.string(from: date) let predicate = NSPredicate(format: "SELF.dateString == %@", dateString) let filteredArray = (groups as NSDictionary).filtered(using: predicate) if var items = filteredArray.first?.value as? [DataItem] { items.append(item) groups[dateString] = items } else { groups[dateString] = [item] } } // 将分组后的数据按时间先后顺序排序 let sortedGroups = groups.sorted { $0.key < $1.key } // 将所有分组添加到一个数组中 var result = [[DataItem]]() for (_, items) in sortedGroups { result.append(items) } return result } ``` 在这个示例中,我们同样定义了一个`DataItem`结构体来表示数据的名称和时间戳。`groupDataByTime`函数首先将数据按时间先后排序,然后使用`NSPredicate`过滤并分组数据。我们指定`NSPredicate`的格式为`SELF.dateString == %@`,其中`dateString`是我们根据时间戳计算得到的时间字符串,`%@`是用于替换的占位符。通过对字典进行过滤,我们可以得到一个包含指定时间字符串的数组,然后将新的数据项添加到这个数组中。最后,我们将所有分组添加到一个大数组中,按时间先后顺序排序,并返回结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WMSmile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值