一、谓词的基本概念与使用

1、谓词(NSPredicate)用于定义一个逻辑条件,通过该条件可执行搜索或内存中的过滤操作。上一篇文章中介绍的集合都提供了使用谓词对集合进行过滤的方法。OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据。非常方便。在Java中是没有这种技术的,但是有开源的框架已经实现了此功能。

2、创建谓词之后,如果谓词中没有占位符,则可以直接使用NSPredicate的evaluateWithObject:方法计算谓词的结果,该结果总是一个BOOL值;

 #import <Foundation/Foundation.h>
#import "FKUser.h" int main(int argc , char * argv[])
{
@autoreleasepool{
// 创建谓词,要求name的以s开头
NSPredicate* pred = [NSPredicate predicateWithFormat:
@"name like 's*'"];
FKUser* user1 = [[FKUser alloc] initWithName:@"sun"
pass:@""];
// 对user1对象使用谓词执行判断。
BOOL result1 = [pred evaluateWithObject:user1];
NSLog(@"user1的name是否以s开头:%d", result1);
FKUser* user2 = [[FKUser alloc] initWithName:@"bai"
pass:@""];
// 对user1对象使用谓词执行判断。
BOOL result2 = [pred evaluateWithObject:user2];
NSLog(@"user2的name是否以s开头:%d", result2);
}
}

NSPredicate示例

3、谓词本身就代表了一个逻辑条件,计算谓词的结果就返回了BOOL类型的值,谓词一个常用的功能就说对集合进行过滤。当程序使用谓词对集合元素进行过滤时,程序会自动遍历集合元素,并根据集合元素计算谓词的值,只有根据某个集合元素计算谓词并返回YES时,该集合元素才会被保留下来。

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

  • -(NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSArray集合,返回集合中符合谓词条件的元素组成新集合

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

  • -(void)filteredUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSMutableArray集合,剔除该集合中不符合谓词条件的元素

  NSSet提供如下方法使用谓词进行过滤集合:

  • -(NSSet *)filteredSetUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSArray集合,返回集合中符合谓词条件的元素组成新集合

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

  • -(void)filteredUsingPredicate:(NSPredicate *)predicate::使用制定谓词过滤NSMutableSet集合,剔除该集合中不符合谓词条件的元素
 #import <Foundation/Foundation.h>
#import "FKUser.h" int main(int argc , char * argv[])
{
@autoreleasepool{
NSMutableArray* array = [NSMutableArray
arrayWithObjects: [NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],nil];
// 创建谓词,要求该对象自身的值大于50
NSPredicate* pred1 = [NSPredicate predicateWithFormat:
@"SELF > 50"];
// 使用谓词执行过滤,过滤后只剩下值大于50的集合元素
[array filterUsingPredicate:pred1];
NSLog(@"值大于50的元素:%@" , array);
NSSet* set = [NSSet setWithObjects:
[[FKUser alloc] initWithName:@"孙悟空"
pass:@""],
[[FKUser alloc] initWithName:@"金角大王"
pass:@""],
[[FKUser alloc] initWithName:@"猪八戒"
pass:@""],
[[FKUser alloc] initWithName:@"太上老君"
pass:@""],
[[FKUser alloc] initWithName:@"银角大王"
pass:@""], nil];
// 创建谓词,要求该对象的name值中包含'大王'
NSPredicate* pred2 = [NSPredicate predicateWithFormat:
@"name CONTAINS '大王'"];
// 执行过滤,过滤后集合只剩下两个元素
NSSet* newSet = [set filteredSetUsingPredicate:pred2];
NSLog(@"%@" , newSet);
}
}

NSPredicate过滤集合

4、在前面的程序中使用谓词的对象总是固定的,总是用指定对象的固定属性与固定的值进行比较,如果符合条件,则返回YES,否则返回NO。有时候我们需要在谓词表达式中使用变量,则可以考虑在谓词表达式中使用占位符参数,在谓词表达式中支持以下两个占位符参数:

  • %K:该占位符用于动态传入属性名。
  • %@:该占位符用于动态设置属性值。取决于要设置属性值的类型,该占位符也可以改成%d、%g等占位符

  如果谓词中由占位符参数,则需要经过两步来计算谓词的结果:

  1. 调用predicateWithSubstitutionVariables:方法为占位符参数设置参数值,该方法返回一个可用的NSPredicate对象
  2. 执行谓词的evaluateWithObject:方法计算谓词的返回结果
     #import <Foundation/Foundation.h>
    #import "FKUser.h" int main(int argc , char * argv[])
    {
    @autoreleasepool{
    NSSet* set = [NSSet setWithObjects:
    [[FKUser alloc] initWithName:@"孙悟空"
    pass:@""],
    [[FKUser alloc] initWithName:@"金角大王"
    pass:@""],
    [[FKUser alloc] initWithName:@"猪八戒"
    pass:@""],
    [[FKUser alloc] initWithName:@"太上老君"
    pass:@""],
    [[FKUser alloc] initWithName:@"银角大王"
    pass:@""], nil];
    NSString* propPath = @"name";
    NSString* value = @"大王";
    // 创建谓词,该谓词中包含了2个占位符
    // 后面的2个变量用于为占位符设置参数值,因此实际上相当于创建了谓词表达式 "name CONTAINS '大王'"
    NSPredicate* pred = [NSPredicate predicateWithFormat:
    @"%K CONTAINS %@" , propPath , value];
    // 执行过滤,过滤后集合只剩下两个元素
    NSSet* newSet = [set filteredSetUsingPredicate:pred];
    NSLog(@"%@" , newSet);
    // 创建谓词,该谓词表达式中使用%K占位符,该占位符使用pass代替,所以该代码相当于创建谓词表达式 "pass CONTAINS $SUBSTR"
    // $SUBSTR相当于一个变量,需要我们调用时为它设置值
    NSPredicate* predTemplate = [NSPredicate predicateWithFormat:
    @"%K CONTAINS $SUBSTR" , @"pass"];
    // 使用NDDictionary指定SUBSTR的值为'43',这就相当于创建了谓词表达式"pass CONTAINS '43'"
    NSPredicate* pred1 = [predTemplate
    predicateWithSubstitutionVariables:
    [NSDictionary dictionaryWithObjectsAndKeys:
    @"" , @"SUBSTR", nil]];
    // 执行过滤,过滤后集合只剩下两个元素
    NSSet* newSet1 = [set filteredSetUsingPredicate:pred1];
    NSLog(@"%@" , newSet1);
    // 使用NDDictionary指定SUBSTR的值为'59'
    NSPredicate* pred2 = [predTemplate
    predicateWithSubstitutionVariables:
    [NSDictionary dictionaryWithObjectsAndKeys:
    @"" , @"SUBSTR", nil]];
    // 执行过滤,过滤后集合只剩下两个元素
    NSSet* newSet2 = [set filteredSetUsingPredicate:pred2];
    NSLog(@"%@" , newSet2);
    }
    }

    NSPredicate使用占位符

二、谓词表达式语法

1、基本比较运算符:=、==(是否相等);>=、=>(左边是否大于或等于右边);<=、=<(左边是否小于或等于右边);>(左边是否大于右边);<(左边是否小于右边);!=、<>(不等于);BETWEEN(必须满足表达式 BETWEEN{下限,上限} 的格式,在范围内左右取等号)。

2、基本逻辑运算符:

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

3、字符串比较运算符:

  • BEGINSWITH:检查某个字符串是否以指定的某个子串开头
  • ENDSWITH:检查某个字符串是否以指定的某个子串结尾
  • CONTAINS:检查某个字符串是否包含指定的某个子串
  • LIKE:检查某个字符串是否匹配指定的字符串模板
  • MATCHES:检查某个字符串是否匹配指定的正则表达式

  上述方法都是区分大小写的,如果要不区分大小写和重音符号,则可以在运算符后面使用[c]、[d]选项,其中[c]指定不区分大小写,[d]指定不区分重音符号。eg:“name BEGINSWITH[c][d] fkja”,则不管name值是FKJava还是fkjava都将返回YES。

4、操作集合的运算符:

  • ANY、SOME:指定只要集合中任意一个元素满足条件,即可返回YES。
  • ALL:指定所有元素满足才返回YES。
  • NONE:指定没有任何元素满足条件才返回YES。
  • IN:只有当左边的表达式或值出现在右边的集合中才会返回YES。
  • array[index]:返回array数组中索引为index处的元素
  • array[FIRST]:返回array数组中第一个元素
  • array[LAST]:返回array数组中最后一个元素
  • array[SIZE]:返回array数组中元素的个数。

5、直接量:

  在谓词表达式中,使用双引号和单引号的效果是一样的。但是单引号只能用单引号结束,不能混用。

  • FALSE、NO:逻辑假
  • TRUE、YES:逻辑真
  • NULL、NIL:代表一个空值
  • SELF:代表正在被判断的对象
  • "text"或'text':代表字符串
  • 数组:数组元素用英文字符隔开。eg:{'keli','zhangsan','lisi','wangwu'}
  • 数值直接量:包括整数、小数、科学计数法
  • 十六进制数:以0x开头
  • 八进制数:以0o开头
  • 二进制数:以0b开头

OC学习14——谓词的更多相关文章

  1. OC学习篇之---谓词(NSPredicate)

    在前一篇文章中我们介绍了OC中一个重要技术通知:http://blog.csdn.net/jiangwei0910410003/article/details/41923401,今天我们在来看一下OC ...

  2. OC学习篇之---总结和学习目录

    今天终于把OC的基础知识学习完了,但是这些知识只是最基础的,还有很多高级知识,这个可能需要后面慢慢的去学习才能体会到.下面就是这次学习OC的目录教程,如果大家发现有什么不正确的地方,请指正,小弟是新生 ...

  3. OC学习总结之面向对象和类

    OC学习总结之面向对象和类   Objective-c是c语言的母集合,它的原意就是在原始的c语言的主体上加入面向对象的特性.1.面向对象和面向过程  面向对象和面向过程是编程的两种思考方式.面向对象 ...

  4. IOS开发-OC学习-常用功能代码片段整理

    IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是 ...

  5. OC学习16——对象归档

    转载自  OC学习篇之---归档和解挡 OC中的归档就是将对象写入到一个文件中,Java中的ObjectInputStream和ObjectOutputStream来进行操作的.当然在操作的这些对象都 ...

  6. OC学习11——循环引用与@class

    转载自 OC学习篇之---@class关键字的作用以及#include和#import的区别 一.#import和#include的区别 当我们在代码中使用两次#include的时候会报错:因为#in ...

  7. OC学习9——反射机制

    1.OC提供了3种编程方式与运行环境进行交互: 直接通过OC的源代码:这是最常见的方式,开发人员只是编写OC源代码,而运行环境负责在后台工作. 通过NSObject类中定义的方法进行动态编程:因为绝大 ...

  8. OC学习6——面相对象的三大特性

    我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这也是面向对象的三大特征.OC学习篇之---类的三大特性(封装,继承,多态) 1.封装(Encapsulation)是指将对象的状态信息 ...

  9. OC学习5——类和对象

    1.OC是在C语言基础上进行扩展得到的一门面向对象的程序设计语言,它也提供了定义类.成员变量和方法的基本功能.类可以被认为是一种自定义的数据类型,使用它可以定义变量,所有使用类定义的变量都是指针类型的 ...

随机推荐

  1. 是用Epplus生成Excel 图表

    1.  前言 这是我最近项目刚要的需求,然后在网上找了半天的教材  但是很不幸,有关于Epplus的介绍真的太少了,然后经过了我的不断研究然后不断的采坑,知道现在看到Excel都想吐的时候,终于成功的 ...

  2. open_basedir restriction in effect.文件访问没有权限异常

    本次搭建公司web开发环境遇到了不少坑首先认为可能是设置的目录写入权限问题,后面解决了发现不是 问题在于nginx配置文件进行了网站目录的保护 配置文件/usr/local/nginx/conf/fa ...

  3. select2 取值 遍历 设置默认值

    select2 取值 遍历 设置默认值 本章内容主要介绍Select2 的初始化,获取选中值,设置默认值,三个方法.Select2 美化了单选框,复选框和下拉框,特别是下拉框多选的问题.但同时,Sel ...

  4. c语言的预处理指令分3种   1> 宏定义   2> 条件编译   3> 文件包含

    宏简介 1.C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 所有的预处 ...

  5. Python简单爬虫

    爬虫简介 自动抓取互联网信息的程序 从一个词条的URL访问到所有相关词条的URL,并提取出有价值的数据 价值:互联网的数据为我所用 简单爬虫架构 实现爬虫,需要从以下几个方面考虑 爬虫调度端:启动爬虫 ...

  6. Mysql--数据的操作

    1.插入数据 1.1 插入完整数据记录 语法1: 例子: 语法2: 例子: 1.2 插入数据记录一部分 语法: 例子: 1.3 插入多条数据记录 1.插入多条完整的数据 语法: 例子:   插入多条部 ...

  7. [WPF]本地化入门

    1. 前言 WPF的本地化是个很常见的功能,我做过的WPF程序大部分都实现了本地化(不管最终有没有用到).通常本地化有以下几点需求: 在程序启动时根据CultureInfo.CurrentUICult ...

  8. MySQL 性能优化的最佳20多条经验分享(一)(转)

    当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库.希望下面的这 ...

  9. C#_表达式目录树的应用

    使用表达式目录树实现两个不同类型的属性赋值: public class People { public int Age { get; set; } public string Name { get; ...

  10. js内置构造函数属性修改问题

    在学习js原型时遇到一个问题,Array,Object等内置构造函数部分属性无法修改,我猜测可能是因为浏览器实现的原因造成的. 1.修改name属性无效. <script type=" ...