2012-03-09 13 views
5

私は、順番にデータの配列を持っていて、述語を渡す内部配列のいずれかに基づいて外側の配列をフィルタリングしようとしている、不親切な配列の辞書を持っています。私はこの作業をするためにNSPredicateを作成することはできません。私は始めて:NSPredicateサブクエリの構文

NSPredicate *lookupPredicate = [NSPredicate predicateWithFormat: 
      @"row_values.property_id == %@ AND row_values.property_value == %@", 
       @"47cc67093475061e01000540", @"Male"]; 

[dataRows filterUsingPredicate:lookupPredicate]; 

これは値を返しません。私はさまざまな形のANYを試しましたが、解析するものは見つけられないようです。ここでも目的は、内側の配列辞書コンテンツのANYの述語が真である外側の配列辞書のみを保持することです。私はこの仕事をするための命題を考え出すことで一日を噛んでいるのを見ることができます...どんなアイディアですか?

dataRows: 
(
{ 
    row = 1; 
    "row_values" =  (
      { 
       "property_id" = 47cc67093475061e01000542; 
       "property_value" = "Mr."; 
      }, 
      { 
       "property_id" = 47cc67093475061e01000540; 
       "property_value" = Male; 
      } 
    ); 
}, 
{ 
    row = 2; 
    "row_values" =  (
      { 
      "property_id" = 47cc67093475061e01000542; 
      "property_value" = "Ms."; 
      }, 
... 
    } 
} 
+0

[コアデータのNSPredicateのSUBQUERY機能のドキュメントはどこにありますか?](http://stackoverflow.com/questions/3076618/where-to-find-the-documentation-of-the- subquery-feature-of-core) – Senseful

答えて

21

男は、 "unfriendly"はその配列の控えめです!

NSArray *dataRows = @[ 
         @{ @"row" : @"1", 
         @"row_values" : @[ 
              @{ @"property_id" : @"47cc67093475061e01000542", 
               @"property_value" : @"Mr." }, 
              @{ @"property_id" : @"47cc67093475061e01000540", 
               @"property_value" : @"Male" } 
              ] 
         }, 
         @{ @"row" : @"2", 
         @"row_values" : @[ 
              @{ @"property_id" : @"47cc67093475061e01000542", 
               @"property_value" : @"Ms." }, 
              @{ @"property_id" : @"47cc67093475061e01000540", 
               @"property_value" : @"Female" } 
              ] 
         } 
        ]; 

NSPredicate *p = [NSPredicate predicateWithFormat:@"SUBQUERY(row_values, $rv, $rv.property_id = %@ AND $rv.property_value = %@)[email protected] > 0", @"47cc67093475061e01000540", @"Male"]; 

NSArray *filtered = [dataRows filteredArrayUsingPredicate:p]; 

それでは、この述語が何をしているか見てみましょう:

OK、私はこれを考え出したと思います。最も外側のレベルに

  1. スタート:

    SUBQUERY([stuff])[email protected] > 0 
    

    AはSUBQUERYオブジェクトの配列を返します。 のdataRows配列にSUBQUERYを実行し、その辞書のSUBQUERYの何かを返すすべての辞書を集計するとします。したがって、SUBQUERYを実行してから(コレクションを返すので)、そこにいくつのアイテムがあるかを尋ねて([email protected])、それが0より大きいかどうかを確認します。存在する場合、最上位のディクショナリは最終的にフィルタリングされたアレイ。 SUBQUERYの中

  2. 掘る:キーのパス、変数、および述語:

    SUBQUERY(row_values, $rv, $rv.property_id = %@ AND $rv.property_value = %@) 
    

    おきSUBQUERYへの3つのパラメータがあります。キーパスは、反復処理するオブジェクトのプロパティです。 SUBQUERYは最外部の辞書で評価されているので、その辞書の@"row_values"を求めて配列を返すことにします。 SUBQUERYは、row_valuesコレクションのアイテムを繰り返し処理します。

    変数は、コレクション内の各アイテムを呼び出すものです。この場合、単純に$rv(「行の値」の省略形)になります。我々の場合、はrow_valuesの「プロパティ」が辞書の配列であるため、NSDictionaryになります。

    最後に、述語が実行され、$rvが順番に各辞書に置き換えられます。この場合、ある辞書が特定のproperty_idと特定のproperty_valueを持っているかどうかを調べたいとします。 の場合は、新しい配列に集約され、それはSUBQUERYから返される配列です。

    SUBQUERYは、私たちが探しているもののproperty_idproperty_valueを持つすべてのrow_valuesの配列を作成しようとしています。

そして、私はこのコードを実行すると、最終的に、私が手:

(
     { 
     row = 1; 
     "row_values" =   (
         { 
       "property_id" = 47cc67093475061e01000542; 
       "property_value" = "Mr."; 
      }, 
         { 
       "property_id" = 47cc67093475061e01000540; 
       "property_value" = Male; 
      } 
     ); 
    } 
) 
+1

実際はソース構造を単純化したので、はるかに簡単な述語を使用できます。冗談...ありがとうDave !!これは完璧に機能し、理にかなっています。私は本当に助けに感謝し、黒のRGB値や英語の母音の数などの助けが必要な場合は教えてください。 – michael

+1

あなたは素晴らしいです、ありがとう、Dave! – flypig

0

AppleのSUBQUERYのドキュメントは、いくつかの場所に散在しています。

サブクエリの発現のための文字列の形式は次のとおりです。

式がある

SUBQUERY(collection_expression, variable_expression, predicate);

コレクションに評価される述語式、variableExpressionは個々の個体を含むために使用される式ですコレクションのすべての要素であり、述語は、その要素が結果コレクションに属しているかどうかを判断するために使用される述語です。

詳細については、my answer to a similar question about the documentation for SUBQUERY syntaxを参照してください。

関連する問題