[Mac][iOS] NSCompoundPredicate で条件をまとめる

2011年1月10日月曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Core Data を使ったアプリケーションで下のような検索機能を実装している。

設定された値を元に NSPredicate を作成し、Core Data に対して検索をかけるのだが、こういう場合に NSCompoundPredicate が役に立つ。
NSCompoundPredicate Class Reference

各々の条件は必ずしも指定されるわけではないので検索条件の項目は可変となる。普通の NSPredicate を使う場合、条件の有無によって文字列の連結を使って条件を構成する必要がある。こんな感じ。
NSMutableString* fmt = [NSMutableString string];
NSMutableArray* array = [NSMutableArray array];
if (name) {
    [fmt appendString:@"name == %@"];
    [array addObject:model.name];
}
if (customerType) {
    if ([fmt lenght] > 0) {
        [fmt appendString:@" AND "];
    }
    [fmt appendString:@"customerType == %@"];
    [array addObject:model.customerType];
  :

NSPredicate* predicate = [NSPredicate predicateWithFormat:fmt argumentArray:array];
これはこれで動くのだが NSCompoundPredicate を使うともっと簡潔に書ける。こんな感じ。

NSMutableArray* array = [NSMutableArray array];
if (name) {
    [array addObject:[NSPredicate predicateWithFormat:@"name == %@", model.name]];
}
if (customerType) {
    [array addObject:[NSPredicate predicateWithFormat:@"customerType == %@",
        model.customerType]];
}
  :
NSPredicate* predicate = [NSCompoundPredicate andPredicateWithSubpredicates:array];
上記は AND接続だったが他に OR, NOT が用意されている。

(a AND b) OR (c AND b) とやりたい場合は NSCompundPredicate を複数使えば良い。
NSPredicate* a, b, c, d;
a = ....;
b = ....;
c = ....;
d = ....;
NSPredicate* r1, r2, r3;
r1 = [NSPridicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:a, b, nil]];
r2 = [NSPridicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:c, d, nil]];
r3 = [NSPridicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:r1, r2, nil]];
条件内のカッコ( ) は自動的に付く。組み立てた条件は NSLogで NSPredicate を表示すれば確認できる。

notPredicateWithSubpredicate: を使った場合、頭に NOT が付く。
NSPredicate* a = [NSPredicate predicateWithFormat:@"name == %@", name];
NSPredicate* r = [NSCompoundPredicate noPredicateWithSubpredicate:a];
この時 r は NOT (name == @"hogehoge") となる。

Responses

Leave a Response

人気の投稿(過去 30日間)