NSPredicate子查询语法 [英] NSPredicate subquery syntax

查看:139
本文介绍了NSPredicate子查询语法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些不友好的字典数组,而这些字典又有数据数组,我试图根据传递谓词的任何内部数组来过滤外部数组。我似乎无法创建一个NSPredicate来使这项工作。我开始时:

I have sort of an unfriendly array of dictionaries that in turn have arrays of data and I am trying to filter the outer array based on any of the inner array passing a predicate. I can't seem to create an NSPredicate to make this work. I started off with:

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

[dataRows filterUsingPredicate:lookupPredicate];

这不返回任何值。我尝试了各种形式的任何形式,但我似乎找不到任何可以解析的东西。同样,目标是仅保留那些外部数组字典,其中内部数组字典内容的任何内容的谓词都为真。我可以看到我咀嚼一天来弄清楚这项工作的咒语...任何想法?

This returns no values. I've tried various forms of ANY but I can't seem to find anything that it will parse. Again, the goal is to only keep those outer array dictionaries where the predicate for ANY of the inner array dictionary content is true. I can see me chewing up a day on figuring out the incantation to make this work... any ideas?

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.";
           },
 ...
   }
}


推荐答案

男人,不友好是对这个数组的轻描淡写!

Man, "unfriendly" is an understatement on that array!

好吧,我想我想出来了:

OK, I think I figured this out:

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 = %@).@count > 0", @"47cc67093475061e01000540", @"Male"];

NSArray *filtered = [dataRows filteredArrayUsingPredicate:p];

所以让我们看看这个谓词在做什么。

So let's see what this predicate is doing.


  1. 从最外层开始:

  1. Start with the outer-most level:

SUBQUERY([stuff]).@count > 0

A SUBQUERY 返回一个对象数组。我们将在 dataRows NSDictionary 上运行此 SUBQUERY $ c>数组,我们希望聚合该字典中 SUBQUERY 返回某些内容的所有词典。所以我们运行 SUBQUERY ,然后(因为它返回一个集合),询问它中有多少项(。@ count )并查看是否大于0.如果是,则顶级字典将位于最终过滤的数组中。

A SUBQUERY returns an array of objects. We're going to run this SUBQUERY on every NSDictionary in the dataRows array, and we want to aggregate all of the dictionaries where the SUBQUERY on that dictionary returns something. So we run the SUBQUERY, and then (since it returns a collection), ask it for how many items were in it (.@count) and see if that's greater than 0. If it is, then the top-level dictionary will be in the final filtered array.

深入 SUBQUERY

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

有三个参数可供选择每个 SUBQUERY :一个关键路径,一个变量和一个谓词。关键路径是我们将要迭代的对象的属性。由于 SUBQUERY 正在最外面的词典上进行评估,我们将要求 @row_values那个字典并取回一个数组。然后 SUBQUERY 将遍历 row_values 集合中的项目。

There are three parameters to every SUBQUERY: A key path, a variable, and a predicate. The key path is the property of the object that we're going to be iterating. Since the SUBQUERY is being evaluated on the outer-most dictionaries, we're going to ask for the @"row_values" of that dictionary and get back an array. The SUBQUERY will then iterate over the items in the row_values collection.

变量是我们要调用的集合中的每个项目。在这种情况下,它只是 $ rv (行值的缩写)。在我们的例子中,每个 $ rv 将是 NSDictionary ,因为 row_values property是一个字典数组。

The variable is what we're going to call each item in the collection. In this case, it's simply going to be $rv (shorthand for "row value"). In our case, each $rv will be an NSDictionary, since the row_values "property" is an array of dictionaries.

最后,谓词将被执行, $ rv 依次替换每个字典。在这种情况下,我们想看看字典是否有某个 property_id 和某个 property_value 如果它,它将被聚合到一个新数组,这是将从 SUBQUERY 返回的数组

Finally, the predicate is going to be executed, with the $rv getting replaced for each dictionary in turn. In this case, we want to see if the dictionary has a certain property_id and a certain property_value. If it does, it will be aggregated into a new array, and that is the array that will be returned from the SUBQUERY.

所以说不同的方式, SUBQUERY 将构建一个包含所有数组的数组我们正在寻找的 property_id property_value 的row_values。

So to say it a different way, the SUBQUERY is going to build an array of all the row_values that have a property_id and property_value of what we're looking for.

最后,当我运行此代码时,我得到:

And finally, when I run this code, I get:

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

这篇关于NSPredicate子查询语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆