2012-03-09 47 views
5

我有一種不友好的字典數組,它依次具有數據數組,我試圖根據任何傳遞謂詞的內部數組來過濾外部數組。我似乎無法創建一個NSPredicate來完成這項工作。我開始與:NSPredicate子查詢語法

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

[dataRows filterUsingPredicate:lookupPredicate]; 

這將返回沒有值。我嘗試了各種形式的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 for Core Data的SUBQUERY功能的文檔?](http://stackoverflow.com/questions/3076618/where-to-find-the-documentation-of-the- subquery-feature-of-nspredicate-for-core) – Senseful 2016-08-07 23:32:21

回答

21

男人,「不友好」是對該陣列的輕描淡寫!

OK,我想我想通了這一點:

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]; 

所以讓我們看看這個謂詞在做什麼。

  1. 開始與最外面的電平:

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

    SUBQUERY返回對象的數組。我們將在dataRows陣列中的每個NSDictionary上運行此SUBQUERY,並且我們想要聚合該字典上的SUBQUERY返回某些東西的所有字典。所以我們運行SUBQUERY,然後(因爲它返回一個集合),詢問它有多少項([email protected]),看看它是否大於0.如果是,那麼頂級字典將在最終過濾數組。

  2. 挖到SUBQUERY

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

    有三個參數,以每SUBQUERY:一個關鍵路徑,變量,和謂詞。關鍵路徑是我們要迭代的對象的屬性。由於SUBQUERY正在評估最外面的字典,我們將要求該字典的@"row_values"並取回數組。然後SUBQUERY將迭代row_values集合中的項目。

    變量是我們要調用集合中的每個項目的東西。在這種情況下,它只是$rv(「行值」的縮寫)。在我們的例子中,每個$rv將是NSDictionary,因爲row_values「屬性」是一組字典。

    最後,謂詞將被執行,依次爲每個字典替換$rv。在這種情況下,我們想要查看字典是否有一定的property_id和某個property_value如果它確實是,它將被聚合成一個新的數組,,這就是將從SUBQUERY返回的數組。

    所以要說這是一種不同的方式,SUBQUERY將建立一個所有row_values數組,其中有我們正在尋找的property_idproperty_value

最後,當我運行此代碼,我得到:

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

其實我只是簡化了源代碼結構,所以我可以使用更簡單的謂詞。開玩笑......非常感謝你戴夫!這工作完美,它是有道理的。我非常感謝幫助,並告訴我如果您需要幫助,例如黑色的RGB值或英語中有多少元音 - 我可以處理的東西。 – michael 2012-03-09 17:09:57

+1

你真了不起,謝謝戴夫! – flypig 2012-11-22 10:53:58

0

蘋果SUBQUERY文檔分散在幾個地方。描述的文檔/語法SUBQUERY

爲子查詢表達式的字符串格式是:

SUBQUERY(collection_expression, variable_expression, predicate);

其中表達是一個謂詞表達式,用於評估一個集合,variableExpression是一個將被用來包含每個個體的表達式集合的元素,謂詞是用於確定元素是否屬於結果集合的謂詞。

有關更多詳細信息和示例,請參閱my answer to a similar question about the documentation for SUBQUERY syntax