NSPredicate官方文档翻译

Using Predicates

如何使用Predicates的官方文档

Evaluating Predicates

To evaluate a predicate, you use the NSPredicate methodevaluateWithObject: and pass in the object against which the predicate will be evaluated. The method returns a Boolean value—in the following example, the result isYES.result的结果为YES。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", @[@"Stig", @"Shaffiq", @"Chris"]];

BOOL result = [predicate evaluateWithObject:@"Shaffiq"];

可以对一个Class使用predicates,但是这个类必须支持key-value编码对于你想要predicate的keys。

对数组使用predicates。

可以使用predicates过滤数组中的一个元素,返回新的过滤有的数组。通过使用fileredArrayUsingPredicate.里面使用了一些语法,例如:SELF beginwith[c] 'a',以a开头的字符串,SELF contains[c] 'e' 包含e的字符串。

NSMutableArray *array =

    [NSMutableArray arrayWithObjects:@"Nick", @"Ben", @"Adam", @"Melissa", nil];

 

NSPredicate *bPredicate = [NSPredicate predicateWithFormat:@"SELF beginswith[c] 'a'"];

NSArray *beginWithB = [array filteredArrayUsingPredicate:bPredicate];

// beginWithB contains { @"Adam" }.

 

NSPredicate *sPredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] 'e'"];

[array filterUsingPredicate:sPredicate];

// array now contains { @"Nick", @"Ben", @"Melissa" }

If you use the Core Data framework, the array methods provide an efficient means of filtering an existing array of objects without—as a fetch does—requiring a round trip to a persistent data store.

Using Predicates with Key-Paths

下面的代码用于找出属于某个部门的特定名字的员工。

NSString *departmentName = ... ;

NSPredicate *predicate = [NSPredicate predicateWithFormat:

        @"department.name like %@", departmentName];

上面语句就只是一个过滤条件。


可以使用ANY代表不限制部门,是要名字符合匹配条件就可以了。

NSPredicate *predicate = [NSPredicate predicateWithFormat:

    @"ANY employees.firstName like 'Matthew'"];

任何部门的员工工资高于多少

float salary = ... ;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY employees.salary > %f", salary];

Null Values

不会匹配空值,即对某类属性没有设置初始值的值,但是对于设置了null(nil)或者NSNull null的除外。如如下例子:

NSString *firstName = @"Ben";

 

NSArray *array = @[ @{ @"lastName" : "Turner" },

                    @{ @"firstName" : @"Ben", @"lastName" : @"Ballard",

                       @"birthday", [NSDate dateWithString:@"1972-03-24 10:45:32 +0600"] } ];

 

NSPredicate *predicate =

    [NSPredicate predicateWithFormat:@"firstName like %@", firstName];

NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];

 

NSLog(@"filteredArray: %@", filteredArray);

// Output:

// filteredArray ({birthday = 1972-03-24 10:45:32 +0600; \\

                      firstName = Ben; lastName = Ballard;})
</pre><p>从上面的代码可以看出,predicate只匹配包含Ben的firstName,对于没有firstName值的不匹配。下面代码段列举了用了一个时间大于多少的例子。用时间来作为比较来验证不匹配没有设置值的情况。</p><p class="p2"></p><pre name="code" class="objc">NSDate *referenceDate = [NSDate dateWithTimeIntervalSince1970:0];

 

predicate = [NSPredicate predicateWithFormat:@"birthday > %@", referenceDate];

filteredArray = [array filteredArrayUsingPredicate:predicate];

 

NSLog(@"filteredArray: %@", filteredArray);

// Output:

// filteredArray: ({birthday = 1972-03-24 10:45:32 +0600; \\

                       firstName = Ben; lastName = Ballard;})

测试NULL

如果想匹配空值,必须特殊制定,就像下面代码一样使用firstName == nil

predicate = [NSPredicate predicateWithFormat:@"(firstName == %@) || (firstName = nil)", firstName];

filteredArray = [array filteredArrayUsingPredicate:predicate];

NSLog(@"filteredArray: %@", filteredArray);

 

// Output:

// filteredArray: ( { lastName = Turner; }, { birthday = 1972-03-23 20:45:32 -0800; firstName = Ben; lastName = Ballard; }

//以下测试ok都为YES
predicate = [NSPredicate predicateWithFormat:@"firstName = nil"];

BOOL ok = [predicate evaluateWithObject:[NSDictionary dictionary]];

 

ok = [predicate evaluateWithObject:

    [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"firstName"]];

对Core Data使用predicates

对Core Data使用predicates和对其他类型数据使用的方法是一样的。也可以对request使用prediactes


限制:没有必要将SQL转换成predicates的形式

SELECT t1.name, V1, V2

    FROM table1 t1 JOIN (SELECT t2.name AS V1, count(*) AS V2

        FROM table2 t2 GROUP BY t2.name as V) on t1.name = V.V1

into a fetch request. You must fetch the objects of interest, then either perform a calculation directly using the results, or use an array operator.

Fetch Requests

以下的例子就是列出工资高于特定数量的员工。(表示对Request还看不太懂)

NSFetchRequest *request = [[NSFetchRequest alloc] init];

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Employee"

        inManagedObjectContext:managedObjectContext];

[request setEntity:entity];

 

NSNumber *salaryLimit = <#A number representing the limit#>;

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"salary > %@", salaryLimit];

[request setPredicate:predicate];

NSError *error;

NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];


使用正则表达式来匹配

NSArray *array = @[@"TATACCATGGGCCATCATCATCATCATCATCATCATCATCATCACAG",

                   @"CGGGATCCCTATCAAGGCACCTCTTCG", @"CATGCCATGGATACCAACGAGTCCGAAC",

                   @"CAT", @"CATCATCATGTCT", @"DOG"];

 

// find strings that contain a repetition of at least 3 'CAT' sequences,匹配包含至少3个连续的‘CAT’的字符串

// but not followed by a further 'CA'但是CAT<span style="font-family: Arial, Helvetica, sans-serif;">后面不包含‘CA’,因为这个第一个不匹配</span>
NSPredicate *catPredicate =

    [NSPredicate predicateWithFormat:@"SELF MATCHES '.*(CAT){3,}(?!CA).*'"];

 

NSArray *filteredArray = [array filteredArrayUsingPredicate:catPredicate];

// filteredArray contains just 'CATCATCATGTCT'结果

According to the ICU specification, 在pattern set中正则表达式无效。 For example, the regular expression\d{9}[\dxX] does not match valid ISBN numbers (any ten digit number, or a string with nine digits and the letter 'X') since the pattern set ([\dxX]) contains a metacharacter (\d). Instead you could write anOR expression, as shown in the following code sample:就是正则表达式的基本语法,有什么不一样?

NSArray *isbnTestArray = @[@"123456789X", @"987654321x", @"1234567890", @"12345X", @"1234567890X"];

NSPredicate *isbnPredicate =

    [NSPredicate predicateWithFormat:@"SELF MATCHES '\\\\d{10}|\\\\d{9}[Xx]'"];

 

NSArray *isbnArray = [isbnTestArray filteredArrayUsingPredicate:isbnPredicate];

// isbnArray contains (123456789X, 987654321x, 1234567890)

Performance性能,考虑性能匹配语句应该注意先后顺序。应该就简单的语句放在正则表达式之前。thus instead of using a predicate shown in the following example:

NSPredicate *predicate = [NSPredicate predicateWithFormat:

    @"( title matches .*mar[1-10] ) OR ( type = 1 )"];

you should write
NSPredicate *predicate = [NSPredicate predicateWithFormat:

    @"( type = 1 ) OR ( title matches .*mar[1-10] )"];

第二个例子中,只有单第一条语句为false时,正则表达式才执行。

Joins

In general, joins (queries that cross relationships) are also expensive operations, and you should avoid them if you can. When testing to-one relationships, if you already have—or can easily retrieve—the relationship source object (or its object ID), it is more efficient to test for object equality than to test for a property of the source object. Instead of writing the following:

NSPredicate *predicate = [NSPredicate predicateWithFormat:

        @"department.name like %@", [department name]];
下面的语句效率更高。
it is more efficient to write:

NSPredicate *predicate = [NSPredicate predicateWithFormat:

        @"department == %@", department];

就是应该避免使用departmanent.name。比如,@"firstName beginswith[cd] 'Matt' AND (ANY directreports.paygrade <= 7)" 的效率更高对于@"(ANY directreports.paygrade <= 7) AND (firstName beginswith[cd] 'Matt')" 因为也是先匹配第一条语句,只有第一条为YES才会执行后面的语句。

Structuring Your Data

In some situations, there may be tension between the representation of your data and the use of predicates. If you intend to use predicates in your application, the pattern of typical query operations may influence how you structure your data. In Core Data, although you specify entities and entity-class mapping, the levels that create the underlying structures in the persistent store are opaque. Nevertheless, you still have control over your entities and the properties they have.

In addition to tending to be expensive, joins may also restrict flexibility. It may be appropriate, therefore, to de-normalize your data. In general—assuming that queries are issued often—it may be a good trade-off to have larger objects, but for it to be easier to find the right ones (and so have fewer in memory).

Using Predicates with Cocoa Bindings

In OS X, you can set a predicate for an array controller to filter the content array. You can set the predicate in code (usingsetFilterPredicate:). You can also bind the array controller’sfilterPredicate binding to a method that returns an NSPredicate object. The object that implements the method may be the File's Owner or another controller object. If you change the predicate, remember that you must do so in a key-value observing compliant way (seeKey-Value Observing Programming Guide) so that the array controller updates itself accordingly.

You can also bind the predicate binding of anNSSearchField object to thefilterPredicate of an array controller. A search field’spredicate binding is a multi-value binding, described in “Binding Types”.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值