如何通过带有键的嵌套数组进行谓词化

时间:2013-08-14 19:16:26

标签: ios nspredicate

我有一个名为self.eventsArray的数组,如下所示:

[ 
  {
        "artist": [
            {
                "artist_name": "Dillon Francis", 
                "name": "Dillon Francis", 
            }, 
            {
                "artist_name": "Major Lazer", 
                "name": "Major Lazer", 
            }, 
            {
                "artist_name": "Flosstradamus ", 
                "name": "Flosstradamus", 
            }
        ],  
        "name": "Mad Decent Block Party NYC", 
    },
  {
        "artist": [
            {
                "artist_name": "Ryan Raddon", 
                "name": "Kaskade", 
            }
        ], 
        "name": "Kaskade Atmosphere Tour NYC", 
    },
]

我一直尝试使用NSPredicate两次来过滤它。当用户搜索时,需要按名称(在艺术家数组中)或名称(在顶级数组中)进行过滤。

NSPredicate *predicateEventsByName = [NSPredicate predicateWithFormat:@"SELF.%K contains[c] %@",@"name",searchText];
NSPredicate *predicateEventsByArtistName = [NSPredicate predicateWithFormat:@"SELF.%K.%K contains[c] %@",@"artist",@"name",searchText];

NSMutableArray *unfilteredEventsArray = [[NSMutableArray alloc] initWithCapacity:0];
unfilteredEventsArray = [NSMutableArray arrayWithArray:[self.eventsArray filteredArrayUsingPredicate:predicateEventsByName]];
[unfilteredEventsArray addObjectsFromArray:[self.eventsArray filteredArrayUsingPredicate:predicateEventsByArtistName]];


 [self.filteredEventsArray addObjectsFromArray:[[NSSet setWithArray:unfilteredEventsArray] allObjects]];

使用此代码,self.filteredEventsArray将填充与顶级"name"匹配的任何搜索字词。它不会为嵌套艺术家"name"提供任何搜索结果。 我怀疑它不会搜索嵌套数组的原因是因为这一行:

NSPredicate *predicateEventsByArtistName = [NSPredicate predicateWithFormat:@"SELF.%K.%K contains[c] %@",@"artist",@"name",searchText];

但我无法弄清楚如何更改predicateWithFormat:以使其搜索嵌套数组。

1 个答案:

答案 0 :(得分:11)

“artist”是一个数组,因此你必须在谓词中使用“ANY”:

[NSPredicate predicateWithFormat:@"ANY %K.%K CONTAINS[c] %@",
              @"artist",@"name",searchText];

请注意,不要手动构建搜索结果的“联合”, 你可以使用“复合谓词”:

NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:
                          @[predicateEventsByName, predicateEventsByArtistName]];
self.filteredEventsArray = [self.eventsArray filteredArrayUsingPredicate:predicate];