Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quick Explanation of SUBQUERY in NSPredicate Expression

There appears to be zero documentation about the SUBQUERY keyword from Apple and I can't find a simple explanation about it on SO or on Google. It's a conspiracy! ;)

Please, could someone from the inner-circle please just provide a quick explanation of its syntax so I can use it?

SUBQUERY(Bs, $x, $x IN %@) 

Thanks

like image 349
pieSquared Avatar asked Sep 28 '10 08:09

pieSquared


1 Answers

And for people who don't quite get what the documentation is saying, a SUBQUERY is essentially this:

SUBQUERY(collection, variableName, predicateFormat) 

And could (simplistically) be implemented like this:

id resultingCollection = ...; //a new collection, either a mutable set or array NSMutableDictionary * substitutions = [NSMutableDictionary dictionary]; NSPredicate * p = [NSPredicate predicateWithFormat:predicateFormat]; for (id variable in collection) {   [substitutions setObject:variable forKey:variableName];   NSPredicate * filter = [p predicateWithSubstitutionVariables:substitutions];   if ([filter evaluateWithObject:collection] == YES) {     [resultingCollection addObject:variable];   } } return resultingCollection; 

So in a nutshell, a SUBQUERY is basically taking a collection of objects and filtering out various objects based on the predicate expression of the SUBQUERY, and returning the resulting collection. (And the predicate itself can contain other SUBQUERYs)

Example:

NSArray * arrayOfArrays = [NSArray arrayWithObjects:                            [NSArray arrayWithObjects:....],                            [NSArray arrayWithObjects:....],                            [NSArray arrayWithObjects:....],                            [NSArray arrayWithObjects:....],                            [NSArray arrayWithObjects:....],                            [NSArray arrayWithObjects:....],                            nil]; NSPredicate * filter = [NSPredicate predicateWithFormat:@"SUBQUERY(SELF, $a, $a.@count > 42)"]; NSArray * filtered = [arrayOfArrays filteredArrayUsingPredicate:filter]; //"filtered" is an array of arrays //the only arrays in "filtered" will have at least 42 elements each 
like image 139
Dave DeLong Avatar answered Oct 04 '22 00:10

Dave DeLong