NSPredicate

Predicate 即谓词逻辑, Cocoa框架中的NSPredicate用于查询,作用是从数据堆中根据条件进行筛选。计算谓词之后返回的结果永远为BOOL类型的值,当程序使用谓词对集合元素进行过滤时,程序会自动遍历其元素,并根据集合元素来计算谓词的值,当这个集合中的元素计算谓词并返回YES时,这个元素才会被保留下来。

最常用的函数:

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

比较运算符 > 、< 、== 、 >= 、<= 、 !=

例:NSNumber *testNumber = @123;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];

if ([predicate evaluateWithObject:testNumber]) {

NSLog(@"testString:%@", testNumber);

  1. 范围运算符:IN 、BETWEEN

BETWEEN {下限,上限}的格式,要求该表达式必须大于或等于下限,并小于或等于上限(两者之间)

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];

  1. 字符串本身:SELF 

    例:@"SELF == 'APPLE'"
  1. 字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
  • BEGINSWITH:检查某个字符串是否以指定的字符串开头
  • ENDSWITH:检查某个字符串是否以指定的字符串结尾
  • CONTAINS:检查某个字符串是否包含指定的字符串
  • LIKE:检查某个字符串是否匹配指定的字符串模板。Like也接受[cd]//?代表一个字符和*代表任意多个字符两个通配符[cd;

例:@"name CONTAIN[cd] 'ang'"   //包含某个字符串

      @"name BEGINSWITH[c] 'sh'"     //以sh字符串开头

      @"name ENDSWITH[d] 'ang'"      //以ang字符串结束、

@"name LIKE[cd] '*er*'"    //*代表通配符, name的值中包含er则返回YES

@"name LIKE[cd] '???er*'" //表示name的第4、5个字符为er时返回YES

注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。

  1. 正则表达式:MATCHES

检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];

正则表达式的实际应用的几种方法:

  1. 判断字符串首字母是否为字母

NSString *regex = @"[A-Za-z]+";

  1. 以A开头,e结尾

NSString *regex = @"^A.+e

  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

NSString * regex M = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";//中国移动:China Mobile

NSString * regex CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";//中国联通:China Unicom

NSString * regex CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";//中国电信:China Telecom

NSString * regex CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";//大陆地区固话及小灵通

  1. 验证email

NSString *strRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}";

  1. 密码组合中要有大写、小写、数字组合:

(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])(?=.*[A-Z]).{6,16}

二、使用谓词过滤集合

程序会自动遍历其元素,它会将自动遍历过之后返回为YES的值重新组合成一个集合返回。

  • NSArray提供了如下方法使用谓词来过滤集合

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

使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合

  • NSMutableArray提供了如下方法使用谓词来过滤集合

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

使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素

  • NSSet提供了如下方法使用谓词来过滤集合

- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSArray中的方法

  • NSMutableSet提供了如下方法使用谓词来过滤集合

- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):

作用同NSMutableArray中的方法。

通过上面的描述可以看出,使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,没有返回值,会直接剔除不符合条件的集合元素(不可变是返回符合的集合元素,可变是剔除不符合。)

三、在谓词中使用占位符参数

想在谓词表达式中使用变量,那么我们需要了解下列三种占位符:

  • %K:用于动态传入属性名:变量名
  • %@:用于动态设置属性值:变量值
  • $VALUE:动态改变的属性值:可以根据你的需要写不同的值,但是必须有$开头

[NSPredicate predicateWithFormat:@"%K CONTAINS %@", @”name”, @”Jack”];

  • //作用:将数组中的name(key)取出含有Jack的组成新数组。

NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];//将数组中的age(key)取出大于value的组成新数组

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

//设置value为25,所以就是在数组age(key中取出大于25的组成新数组。

NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];

//  修改$VALUE的值为32

NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}]; //  修改$VALUE的值为32

NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];

//设置value为32,所以就是在数组age(key中取出大于32的组成新数组,

所以$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]];

对应的数组输出为:

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

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

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

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

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

搜索框的实现

要实现的协议:<UISearchBarDelegate,UISearchResultsUpdating>

#import "ViewController.h"

//全部数据

@property(strong,nonatomic)NSArray *listData;

//过滤后的数组

@property(strong,nonatomic)NSMutableArray *listFilterData;

@property(strong,nonatomic)UISearchController *searchController;

//内容过滤方法

-(void)filterContentsForSearchText:(NSString*)searchText scope:(NSUInteger)scope;

#import "ViewController.m"

//初次进入查询所有数据

[self filterContentsForSearchText:@"" scope:-1];

//实例化UISearchController

self.searchController=[[UISearchController alloc]initWithSearchResultsController:nil];

//设置self为更新搜索结果对象

self.searchController.searchResultsUpdater=self;

//设置搜索背景为灰色

self.searchController.dimsBackgroundDuringPresentation=false;

//设置搜索范围栏中的按钮

self.searchController.searchBar.scopeButtonTitles=@[@"中文",@"英文"];

/设置实现代理

self.searchController.searchBar.delegate=self;

/将搜索栏放在表头中

self.tableView.tableHeaderView=self.searchController.searchBar;

//尺寸自适应

[self.searchController.searchBar sizeToFit];

}

-(void)filterContentsForSearchText:(NSString *)searchText scope:(NSUInteger)scope{

if ([searchText length]==0) {

//查询所有

self.listFilterTeams=[NSMutableArray arrayWithArray:self.listTeams];

return;

}

NSPredicate *scopePredicate;

NSArray *tempArray;

switch (scope) {

case 0://字段为name的字符串

scopePredicate=[NSPredicate  predicateWithFormat:@"SELF.name contains[c]%@",searchText];

//若是只有一个key,则直接用SELF就可以了,如果有多个key(name,image等等),就要明确选择要搜索的key

tempArray=[self.listTeams filteredArrayUsingPredicate:scopePredicate];

self.listFilterTeams=[NSMutableArray arrayWithArray:tempArray];

break;

case 1:

scopePredicate=[NSPredicate predicateWithFormat:@"SELF.image contains[c]%@",searchText];

tempArray=[self.listTeams filteredArrayUsingPredicate:scopePredicate];

self.listFilterTeams=[NSMutableArray arrayWithArray:tempArray];

break;

default:

self.listFilterTeams=[NSMutableArray arrayWithArray:self.listTeams];

break;

}

}

-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:

(NSInteger)selectedScope{

[self updateSearchResultsForSearchController:

self.searchController];

}

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{

NSString *searchString=searchController.searchBar.text;

[self filterContentsForSearchText:searchString scope:searchController.searchBar.selectedScopeButtonIndex];

scope    [self.tableView reloadData];

}

2.直接用代理实现

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {

NSString *searchString = [self.searchController.searchBar text];

NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString];

if (self.searchList!= nil) {

[self.searchList removeAllObjects];

}

//过滤数据

self.searchList= [NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:preicate]];

//刷新表格

[self.tableView reloadData];

}

iOS学习之NSPredictae及搜索框的实现的更多相关文章

  1. IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)

    ********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearc ...

  2. 十七、Android学习笔记_Android 使用 搜索框

    1.在资源文件夹下创建xml文件夹,并创建一个searchable.xml: android:searchSuggestAuthorityshux属性的值跟实现SearchRecentSuggesti ...

  3. [分享]IOS开发-简单实现搜索框显示历史记录的本地缓存及搜索历史每次只能获取到一个的解决方案

    注:原文:http://www.zhimengzhe.com/IOSkaifa/40433.html 1.首先,我们需要对进行过搜索的textField的输入内容进行一个NSUserDefaults的 ...

  4. vue学习(十四) 条件搜索框动态查询表中数据 数组的新方法

    //html <div id="app"> <label> 名称搜索关键字: <input type="text" clasa=& ...

  5. iOS开发——UI篇OC篇&TextField作为搜索框的使用

    TextField作为搜索框的使用 在iOS开发中我们经常会使用到搜索框,但是有的时候系统自带的搜索框不足以满足我吗想要的功能,这个时候我们就可以使用自定义的搜索框实现想要的功能. 今天就简单的介绍一 ...

  6. 【好程序员笔记分享】——iOS开发之使用TextField作为搜索框

    -iOS培训,iOS学习-------型技术博客.期待与您交流!------------ iOS开发之使用TextField作为搜索框     今天给大家带来一个新的技巧,比如平时我们要使用代码创建一 ...

  7. 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar

    猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...

  8. AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar

    AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...

  9. iOS之搜索框UISearchController的使用(iOS8.0以后替代UISearchBar+display)

    在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便地在UITableView中添加搜索框. 而在之前版本中, 我们还是必须使用UISearchBar + UISe ...

随机推荐

  1. 初识Python第三天(二)

    2.2 OrderedDict有序字典 import collections dic = collections.OrderedDict() dic['k1'] = 'v1' dic['k2'] = ...

  2. UBUNTU下Y86模拟器的安装和使用

    UBUNTU下Y86模拟器的安装和使用 由于上周在虚拟机中安装Y86模拟器中出现了一些问题并且没得到解决,所以上周实验是在实验楼上做的,这几天练习了UBUNTU下Y86模拟器的安装和使用. 参考博客: ...

  3. 再次熟悉jdbc连接mysql

    闲来无事想探究一下jdbc 1.首先准备工作.我们要下载jdbc驱动包mysql-connector-java-5.1.7-bin.jar.其他的暂时先不用,这个包的下载地址:http://pan.b ...

  4. 简单练习题2编写Java应用程序。首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”、“取款”和“余额查询”。其次, 编写一个主类,在主类中测试Account类的功能

    编写Java应用程序.首先定义一个描述银行账户的Account类,包括成员变 量“账号”和“存款余额”,成员方法有“存款”.“取款”和“余额查询”.其次, 编写一个主类,在主类中测试Account类的 ...

  5. noi 6045 开餐馆

    题目链接:http://noi.openjudge.cn/ch0206/6045/ 解题报告:参考了konjac 蒟蒻的. 题意: 有N个地址,从中选一些开餐馆,要保证相邻餐馆的距离大于k.问最大利润 ...

  6. [jetbrains系列] 外链第三方库+代码补全设置

    jetbrains系列的IDE真的是太好用了,有种相见恨晚的感觉. 在开发过程中第三方库是必不可少的,在开发的时候如果有一个可以补全的IDE可以节省查文档的时间. 举个例子:给pycharm配pysp ...

  7. php : 匿名函数(闭包) [一]

    摘自: http://www.cnblogs.com/starlion/p/3894578.html 一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函数(Anonymous fu ...

  8. 【树莓派】基于TinyProxy搭建HTTP代理服务器

    一.前言 关于为什么要玩玩HTTP代理就不用我多说了.  二.搭建环境 * Linux laptop 2.6.32-45-generic #100-Ubuntu SMP Wed Nov 14 10:4 ...

  9. Intellij 图标介绍及配置文件常识

    图标 参数名称   含义 默认值   -Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xm ...

  10. 微软2017校招笔试题3 registration day

    题目 It's H University's Registration Day for new students. There are M offices in H University, numbe ...