NSPredicate with nested arrays

2 Solutions Collect From Internet About “NSPredicate with nested arrays”

For more complicated predicate string syntax I usually use predicateWithBlock to evaluate them instead, since it’s much easier to debug and understand. However, for this, if all you want to do is fetch all the questions in a category that contain the given substring I would use:

NSArray *questions = [self arrayByFlattening:[categories valueForKeyPath:@"subcategories.questions"]];
questions = [questions filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"question CONTAINS[cd] %@", substring]];

Where arrayByFlattening is a method to flatten the array.

This method does not work as well if you need to execute it all in one fetch, i.e. if you are using core data with a large sample source and don’t want to fetch more than you need to and then filter the results.

I think this kind of extreme nested data is a very bad idea. It is overly complicated and error prone. Many things are not intuitive. For instance, your predicate would fetch all categories where there is some question that matches your query. You would still get the whole category back, including all questions that do not match the query. To drill down, you would have to filter again.

For this kind of setup, I very much recommend Core Data instead. You could just fetch the necessary questions because in Core Data key paths work in both directions, which is what you need here.

For your particular problem, you would fetch the Question instances that match the predicate

[NSPredicate predicateWithFormat:@"question CONTAINS[cd] %@", substring];

You would get a list of all categories with a succinct expression like

[questions valueForKeyPath:@"subcategory.category"];