iOS中的谓词NSPredicate的使用

  今天写一篇关于iOS中关于谓词一些用法,我们先来看苹果官方给出的解释:

  

  The NSPredicate class is used to define logical conditions used to
constrain a search either for a fetch or for in-memory filtering.

  You use predicates to represent logical conditions, used for
describing objects in persistent stores and in-memory filtering of objects.
Although it is common to create predicates directly from instances of NSComparisonPredicate, NSCompoundPredicate, and NSExpression, you often create predicates from a format
string which is parsed by the class methods on NSPredicate. Examples of predicate format strings include:

  • Simple comparisons, such as grade ==
    "7" or firstName like "Shaffiq"

  • Case and diacritic insensitive lookups, such as name
    contains[cd] "itroen"

  • Logical operations, such as (firstName
    like "Mark") OR (lastName like "Adderley")

  • In OS X v10.5 and later, you can create ??between??
    predicates such as date between {$YESTERDAY,
    $TOMORROW}.

You can create predicates for relationships, such as:

  • group.name like "work*"

  • ALL children.age > 12

  • ANY children.age > 12

  You can create predicates for operations, such as @sum.items.price
< 1000. For a complete syntax reference, refer to the Predicate Programming Guide.

  You can also create predicates that include variables, so that
the predicate can be pre-defined before substituting concrete values at runtime.
In OS X v10.4, for predicates that use variables, evaluation is a two step
process (see predicateWithSubstitutionVariables: and
evaluateWithObject:). In OS X v10.5 and later, you
can use evaluateWithObject:substitutionVariables:, which
combines these steps.

   定义一个谓词的用途是通过定义一个逻辑的条件来过滤信息。

   下面我们来通过代码的方式来看一些谓词的使用。

   下面我们通过定义一个汽车的类来了解谓词。

   汽车类car的头文件定义如下: 


#import <Foundation/Foundation.h>

@class Engine;
@class Tire;

@interface Car : NSObject

@property (nonatomic, copy) Engine *engine;
@property (nonatomic, copy) NSMutableArray *tires;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *make;//制造厂商
@property (nonatomic, copy) NSString *model;
@property (nonatomic, assign) int modelYear;
@property (nonatomic, assign) int numberOfDoors;
@property (nonatomic, assign) float mileage;

- (void)setTire:(Tire*)tire atIndex:(int)index;
@end

   轮胎类头文件定义:


#import <Foundation/Foundation.h>

@interface Engine : NSObject<NSCopying>

@property (nonatomic, assign) NSInteger horsepower;//马力
@end

  车库类头文件的定义:


#import <Cocoa/Cocoa.h>
@class Car;
@interface Garage : NSObject
{
NSString *name;
NSMutableArray *cars;
}
@property (readwrite, copy) NSString *name;
@property (nonatomic, copy) NSMutableArray *cars;
- (void) addCar: (Car *) car;
- (void) print;
@end // Garage

  轮胎类头文件的定义:


#import <Foundation/Foundation.h>

@interface Tire : NSObject

@end

 

  下面是mian函数中的一些初始化的一些定义:


#import <Foundation/Foundation.h>

#import "Car.h"
#import "Tire.h"
#import "Engine.h"
#import "Garage.h"

//下面的方法的作用是重新构造一辆汽车
Car *makeCar (NSString *name, NSString *make, NSString *model, int modelYear, int numberOfDoors,float mileage, int horsepower)
{
Car *car = [[[Car alloc] init] autorelease];
car.name = name;
car.make = make;
car.model = model;
car.modelYear = modelYear;
car.numberOfDoors = numberOfDoors;
car.mileage = mileage;
Engine *engine = [[[Engine alloc] init] autorelease];
[engine setValue: [NSNumber numberWithInt: horsepower]
forKey: @"horsepower"];
car.engine = engine;
// Make some tires.
for (int i = 0; i < 4; i++)
{
Tire * tire= [[[Tire alloc] init] autorelease];
[car setTire: tire atIndex: i];
}
return (car);
} // makeCar


//接下来在mian函数中定义一个车库和里面存放的汽车
int main(int argc, const char * argv[])
{
Garage *garage = [[Garage alloc] init];
garage.name = @"Joe’s Garage";

Car *car;
car = makeCar (@"Herbie", @"Honda", @"CRX", 1984, 2, 110000, 58);
[garage addCar: car];
  


   car = makeCar (@"Badger",
@"Acura", @"Integra",
1987, 5, 217036.7, 130);

   [garage addCar:
car];

  car = makeCar (@"ElvIs", @"Acura", @"Legend", 1989, 4, 28123.4, 151);
  [garage addCar: car];
  
  car = makeCar (@"Phoenix", @"Pontiac", @"Firebird", 1969, 2, 85128.3, 345);  

  [garage addCar: car];
  
  car = makeCar (@"Streaker", @"Pontiac", @"Silver Streak", 1950, 2, 39100.0, 36);
  [garage addCar: car];
  car = makeCar (@"Judge", @"Pontiac", @"GTO", 1969, 2, 45132.2, 370);
  [garage addCar: car];
  car = makeCar (@"Paper Car", @"Plymouth", @"Valiant", 1965, 2, 76800, 105);
  [garage addCar: car];
  car = makeCar (@"Herbie", @"Honda", @"CRX", 1984, 2, 34000, 58);
  [garage addCar: car];
  [garage print];
}

  

  以下谓词的使用都是在main函数中定义的。

  在没有谓词情况下,要判断创建的辆车名是否是叫Herbie的呢?我们可能会使用下面的代码:


    if ([car.name isEqualToString:@"Herbie"]) {
NSLog(@"Match");
}else{
NSLog(@"NotMatch");
}

  

  下面我们来看一下使用谓词的情况下应该怎么做?

// 
  基本的谓词用法,创建了一个谓词,这个谓的判断条件是汽车的name 与Herbie相同

// 
  需要注意的是,如果不使用单引号的话,谓词格式将会把字符串理解成keyPath,如果使用 (keyPath是KVC的使用)

// 
  单引号括起来的话,谓词会理解为字符串

  
   


  NSPredicate *predicate;
  //谓词的初始化
   predicate = [NSPredicate predicateWithFormat:@"name==‘Herbie‘"];
  //谓词的判断条件 (返回一个Boolen值来判断这个对象是否满足上面的谓词条件)
BOOL match = [predicate evaluateWithObject:car];

if (match) {
      NSLog(@"Match");
   }else
  
  {
       NSLog(@"NotMatch");
   }

  看到上面的代码有人会想,这样的方法不是没有上面的代码简单吗?我们来看谓词的其它使用情况

  


    predicate = [NSPredicate predicateWithFormat:@"engine.horsepower > 150"];
match = [predicate evaluateWithObject:car];
if (match) {
NSLog(@"car‘s engine horsepower > 150");
}else
{
NSLog(@"car‘s engine horsepower no > 150");
}

   这样是不是看到谓词的好处了,如果在不使用谓词的情况下,就应该先找到发动机,然后再找发动机马力大于150的,是不是感到繁琐。能过使用谓词就可以一步到位找到。

 

  我们继续来看谓词的其它用法

  //    现在要实现一个功能:将车库里的汽车,凡是发动机马力大于150的全部列出来

   //    在没有谓词的情况下:1、取出车库里的汽车

              2、创建一个可变数据用于存放满足条件的汽车

               
3、遍历车库里的每一辆汽车,判断是否满足条件

              4、如果满足的话,将这辆汽车放到可变数组里。

  下面我们来对比一下使用谓词和不使用谓词来实现上述功能


//不使用谓词的情况 
 
//该方法是从车库中取出所有的汽车,定义在Garage.m中

  NSArray *cars = [garage cars];

   
  NSMutableArray *favCars = [[NSMutableArray alloc] initWithCapacity:3];
for (Car *favCar in cars) {
if (favCar.engine.horsepower > 150) {
[favCars addObject:favCar];
}
}
NSLog(@"my fav car is %@",favCars);
 

//同上的功能,在有谓词的情况下只需要1、创建一个谓词,条件是汽车马力大于150,2、使用谓词得到结果
//定义一个谓词 满足engine.horsepower > 150

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

  //通过谓词给出的条件过滤,

 NSArray *myFavCars = [cars filteredArrayUsingPredicate:predicate];

NSLog(@"myFavCars is %@",myFavCars);

   谓词也可以在外界传递参数


    int horPower = 50;
predicate = [NSPredicate predicateWithFormat:@"engine.horsepower > %d",horPower];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

NSString *carName = @"Herbie";
predicate = [NSPredicate predicateWithFormat:@"name == %@",carName];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

  

  在谓词里有一个格式说明符叫%K(大写),用于表示keyPath


    NSString *keyPath = @"name";
NSString *condition = @"Herbie";
predicate = [NSPredicate predicateWithFormat:@"%K == %@",keyPath,condition];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"xxxxxx%@",myFavCars);

  

 谓词里还有一个比较强大的功能就是占位符($)的使用。注意在使用占位符的时候后面$后面的属性要大写,在使用的时候也要用和定义的时候一样的大写。


  NSPredicate *predicateTemplate = [NSPredicate predicateWithFormat:@"name == $NAME"];

NSDictionary *varDict = [NSDictionary dictionaryWithObjectsAndKeys:@"Herbie",@"NAME", nil];

predicate = [predicateTemplate predicateWithSubstitutionVariables:varDict];

myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"-----%@",myFavCars);

predicateTemplate = [NSPredicate predicateWithFormat:@"engine.horsepower > $POWER"];
varDict = @{@"POWER":@150};
predicate = [predicateTemplate predicateWithSubstitutionVariables:varDict];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"+++++++%@",myFavCars);

  谓词的使用还可以用一些比较运算符和逻辑运算符 如:>
< >= <= != <> 比较运算符

  逻辑运算符与或非相对应的标识符 AND
OR(逻辑运算符全部要大写)


    predicate = [NSPredicate predicateWithFormat:@"(engine.horsepower  < 59) AND (engine.horsepower > 200)"];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
[garage print];
NSLog(@"50-200 %@",myFavCars);

predicate = [NSPredicate predicateWithFormat:@"name < ‘Newton‘"];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

  谓词也可以直接使用硬编码的格式也可以不直接使用,占位符也可以使用

  


//    直接使用硬编码的方式来表示两个数据之间的值的覆盖件

predicate = [NSPredicatepredicateWithFormat:@"engine.horsepower BETWEEN {50,200}"];

myFavCars = [cars filteredArrayUsingPredicate:predicate];

NSLog(@"%@",myFavCars);

//使用变量来表示两个数据值之间的值的条件

  //定义表示范围的值
NSArray *betweens = @[@50,@200];

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

myFavCars = [cars filteredArrayUsingPredicate:predicate];

NSLog(@"%@",myFavCars);

 //占位符来表两个数据之间的值的条件。

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

 varDict = @{@"POWERS"
: @[@50,@200]};

predicate = [predicateTemplate predicateWithSubstitutionVariables:varDict];

myFavCars = [cars filteredArrayUsingPredicate:predicate];

NSLog(@"%@",myFavCars);

  谓词的使用还可以使用集合的概念的情况:(IN)

  


//    创建一个谓词对象, 使用这个对象,查找出车库里车名为Herbie Snugs Badger Flag的汽车的信息
//  就是把名字为下面的全部取出来

predicate = [NSPredicate predicateWithFormat:@"name IN {‘Herbie‘,‘Snugs‘,‘Badger‘,‘Flag‘}"];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);


// SELF 在这里表示的是使谓词进行最终计算的时候的对象,实际就是cars数组里的car对象。
predicate = [NSPredicate predicateWithFormat:@"SELF.name IN {‘Herbie‘,‘Snugs‘,‘Badger‘,‘Flag‘}"];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

// 想把车库里的所有车的名字取出来,使用kvc就可以完成集合的整体操作
NSArray *carNames = [cars valueForKey:@"name"];
NSLog(@"carNames is %@",carNames);
predicate = [NSPredicate predicateWithFormat:@"SELF IN {‘Herbie‘,‘Snugs‘,‘Badger‘,‘Flag‘}"];
myFavCars = [carNames filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

// 需要注意的是, 在谓词格式里面,需要遵守一个规则, 就是关键字大写
// 查找以下两个车库的相同名字的汽车
// {‘Herbie‘,‘Snugs‘,‘Badger‘,‘Flag‘} {‘Judge‘,‘Paper Car‘ ,‘Badger‘,‘Phoenix‘}
// 该方法的作用是比较在两个数组里面共有名字,然后取出来(相当于集合中的取交集)

NSArray *names1 = @[@"Herbie",@"Snugs",@"Badger",@"Flag"];
NSArray *names2 = @[@"Judge",@"Paper Car" ,@"Badger",@"Phoenix"];
predicate = [NSPredicate predicateWithFormat:@"SELF IN %@",names1];
myFavCars = [names2 filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

  在谓词的使用中也可以使用通配符。下面我们来看一下通配符在谓词中的使用。


//    从当前的车库里,找到名字中包含有i字母的汽车

//  这个方法中的作用是把名字中的包含i字母的名字取出来,关键字用的是CONTAINS[cd]其中[]中的c的意思是忽略字母的大小写,d是跟字母的重音有关。
// predicate = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS[cd] %@",@"i"];

//  这个方法使用的是LIKE,下面的判断是名字中含有字母vi。
// predicate = [NSPredicate predicateWithFormat:@"SELF.name LIKE[c] ‘*vi*‘"];

//下面这个也是通配符的使用,使用关键字MATCHES.判断心字母H开头,并且以字母i结束。
predicate = [NSPredicate predicateWithFormat:@"SELF.name MATCHES ‘H[a-z]*i?‘"];
myFavCars = [cars filteredArrayUsingPredicate:predicate];
NSLog(@"%@",myFavCars);

  当然了,也可以在谓词中使用运算符,像SUM来求和之类的,有兴趣的大家可以测试一下,关于谓词的使用就先介绍到这里。

    

  

时间: 2024-11-19 03:33:45

iOS中的谓词NSPredicate的使用的相关文章

iOS:转载:IOS谓词--NSPredicate

IOS谓词--NSPredicate 分类: IOS应用2013-02-19 17:24 6792人阅读 评论(1) 收藏 举报 Cocoa 提供了NSPredicate 用于指定过滤条件,谓词是指在计算机中表示计算真假值的函数,它使用起来有点儿像SQL 的查询条件,主要用于从集合中分拣出符合条件的对象,也可以用于字符串的正则匹配.首先我们看一个非常简单的例子,对谓词有一个认知.#import <Foundation/Foundation.h>@interface Person: NSObje

iOS 之谓词 NSPredicate

NSPredicate:谓词 NSPredicate的具体用途应该还是过滤,类似于过滤条件之类的. 一.NSpredicate的创建: NSpredicate *predicate  = [NSpredicate  predicateWithFormat:@"age > 28"]; //筛选条件       predicateWithFormat:为类方法 ,不需要我们管理内存. 二.NSpredicate中主要的几种运算方式      1.比较运算符 > .< .=

iOS中谓词的使用

Cocoa提供了一个类NSPredicate类,该类主要用于指定过滤器的条件,该对象可以准确的描述所需条件,对每个对象通过谓词进行筛选,判断是否与条件相匹配.谓词表示计算真值或假值的函数.在cocoa中封装的一个数据库框架cocoaData里面 在进行查询(包括模糊查询)时同样会要用到谓词:下面对谓词的使用方法及规则进行简要的介绍下: 1,用predicateWithFormat创建一个谓词 条件 NSString *predicateString [email protected]"name=

OC中给我们提供的一个技术:谓词(NSPredicate).note

OC中给我们提供的一个技术:谓词(NSPredicate)OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据.非常方便.在Java中是没有这种技术的,但是有开源的框架已经实现了此功能. 下面来看一下具体的例子吧: Person.h objc]  view plaincopy  1. //   2. //  Person.h   3.

iOS中3种正则表达式的使用与比较

之前我在博文中介绍过iOS中自带正则表达式的使用( 传送门),后来我发现其实iOS中有三种方式来实现正则表达式的匹配.现在将他们都记录在这里: 1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @“[email protected]163.com”: NSString *regex = @"[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; NSPredic

谓词(NSPredicate)

OC中的谓词操作是针对于数组类型的,他就好比数据库中的查询操作,数据源就是数组,这样的好处是我们不需要编写很多代码就可以去操作数组,同时也起到过滤的作用,我们可以编写简单的谓词语句,就可以从数组中过滤出我们想要的数据.非常方便.在Java中是没有这种技术的,但是有开源的框架已经实现了此功能. 下面来看一下具体的例子吧: Person.h [objc] view plain copy // //  Person.h //  46_NSPredicate // //  Created by jian

iOS中的数据存储

SQLite3 SQLite3是一款开源的嵌入式关系型数据库,可移植性好,易使用,内存开销小. SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中. SQLite3常用的4种数据类型:text(文本字符串), integer(整型值), real(浮点值), blob(二进制数据(比如文件)). 在iOS中使用SQLite3,首先要添加库文件'libsqlite3.dylib'和导入主头文件#import<sqlite3.h> SQL语句的特点: 1> 不区分大

正则表达式在iOS中的运用(附手机密码邮箱等正则判断)

一.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式达到字符串的复杂控制. 二.正则表达式的语法 看几个例子:手机号码,密码(3-30个字符,不允许特殊字符),邮箱判断. - (BOOL)validatePhoneNumber:(NSString *) textString { NSString* number=@"^1[3|4|5|7|8][0-9

正则表达式语法与正则表达式在iOS中的常见用法

一.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式达到字符串的复杂控制. 二.正则表达式的语法 看一个过滤纯数字的例子 - (BOOL)validateNumber:(NSString *) textString { NSString* number=@"^[0-9]+$"; NSPredicate *numberPre = [NSPre