7

NSPredicate を使用してオブジェクトの可変配列をフィルタリングしようとしていますが、フィルタリングしたいプロパティを含むレベルにアクセスできません。

同様のカスタム オブジェクトで構成される簡単な例を挙げます。

  • 祖父母

祖父母の NSMutableArray があり、10 歳の孫を持つすべての祖父母オブジェクトを検索したいと考えています。したがって、孫はルートから 2 レベルの深さになります。Child には age プロパティがあります。

すなわち。Grandparents には配列プロパティ Parents があり、Parents には配列プロパティ Children があり、Children には整数プロパティ age があります。

次の NSPredicate は結果を返しませんでした。"SELF.parents.children.age == 10".

これらはネストされたコレクションであるため、この述語は間違った方法である可能性が高いことを認識していますが、そのレベルにアクセスする方法については行き詰まっています。おそらくサブクエリまたはコレクション演算子を介してですが、解決できません。

心に留めておくべきことの 1 つは、年齢の異なる複数の孫 (そのうちの 1 人は 10 歳) を持つ祖父母が明らかに必要であることです。

4

2 に答える 2

16

「明白な」解決策は、次の述語になります。

"ANY parents.children.age == 10"

ただし、「ANY」演算子は、ネストされた対多の関係では機能しません。したがって、SUBQUERY が必要です。

NSArray *grandParents = your array of GrandParent objects;
NSPredicate *predicate = [NSPredicate
   predicateWithFormat:@"SUBQUERY(parents, $p, ANY $p.children.age == 10).@count > 0"];
NSArray *filtered = [grandParents filteredArrayUsingPredicate:predicate];

備考:

  • SELF述語で使用する必要はありません。filteredArrayUsingPredicate述語をGrandParent配列内の各オブジェクトに適用します。
  • 述語での SUBQUERY の使用法は、十分に文書化されていないようです。NSExpression クラス リファレンスに1 つの例があります。NSPredicate Expression の SUBQUERY の簡単な説明も参照してください。
  • この場合、SUBQUERY 内の述語はParent単一のそれぞれに適用されGrandParentます。SUBQUERY は、10 歳の子供を持つ親を返します。その"SUBQUERY(...).@count > 0"ため、祖父母に 10 歳の子供を持つ親が少なくとも 1 人いる場合、TRUE と評価されます。

追加:サブクエリなしで実際に実行できることがわかりました:

NSPredicate *predicate = [NSPredicate
    predicateWithFormat:@"ANY parents.@unionOfArrays.children.age == 10"];

機能し、望ましい結果が得られます。(SUBQUERY より効果的ではないかもしれませんが、私はそれをテストしませんでした。)

于 2013-05-31T12:16:20.743 に答える