Richard McCluskey
Richard McCluskey

Reputation: 588

How to Predicate through Nested Arrays with Keys

I have an array called self.eventsArray which looks like this:

[ 
  {
        "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", 
    },
]

I have been trying to filter it by using NSPredicate two times. When the user searches, it needs to be filtered by either name (in the artist array) or name (in the top-level array).

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

Using this code, self.filteredEventsArray will be populated with any search term matching the top-level "name". It won't give any search results for the nested artist "name". I suspect the reason why it won't search through the nested array is because of this line:

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

but I can't figure out how to change the predicateWithFormat: to make it search through the nested array.

Upvotes: 2

Views: 2882

Answers (1)

Martin R
Martin R

Reputation: 539925

"artist" is an array, therefore you have to use "ANY" in the predicate:

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

Note that instead of building the "union" of the search results manually, you can use a "compound predicate":

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

Upvotes: 11

Related Questions