2010-09-28 10 views
24

Es scheint keine Dokumentation über das Schlüsselwort SUBQUERY von Apple und ich kann nicht finden Sie eine einfache Erklärung über es auf SO oder auf Google. Es ist eine Verschwörung! ;)Schnelle Erklärung der SUBQUERY in NSPredicate Ausdruck

Bitte, könnte jemand vom inneren Kreis bitte nur eine kurze Erklärung seiner Syntax zur Verfügung stellen, damit ich es benutzen kann?

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

Dank

Antwort

18

This is what a subquery evaluates to. (Gefunden von this mailing list thread, die # 1 Treffer für „NSPredicate Unterabfrage“ in Google.) Das Bit der Dokumentation erklärt auch, wie das Prädikat Format-String-Syntax sie sich bezieht.

+0

Damn! Ich kann nicht glauben, dass ich das vermisst habe. Danke vielmals. – pieSquared

+0

Woher weißt du, welchen Brief zu verwenden? An manchen Stellen sehe ich $ x an einigen Stellen, an denen ich $ s sehe, andere sehe ich $ a, und ich kann per Kontext keine Diff zwischen $ x und $ s sehen. – jpswain

+0

@ orange80: Der Variablenname ist Ihre Wahl. Siehe die Dokumentation, die ich in meiner Antwort verlinkt habe. Wenn Sie Python kennen, ist es wie gesagt: [x für x in der Sammlung if (eine Bedingung mit x)]. Soweit ich weiß, muss der Variablenname nicht einmal ein einzelner Buchstabe sein. –

41

Und für Menschen, die nicht ganz bekommt, was die Dokumentation sagt, ein SUBQUERY ist im Wesentlichen diese:

SUBQUERY(collection, variableName, predicateFormat) 

Und könnte (vereinfachend) wie folgt umgesetzt werden:

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 Kurz gesagt, eine SUBQUERY nimmt im Grunde genommen eine Sammlung von Objekten und filtert verschiedene Objekte basierend auf dem Prädikatausdruck der SUBQUERY heraus und gibt die resultierende Sammlung zurück. (Und das Prädikat kann sich andere SUBQUERY s enthalten)

Beispiel:

NSArray * arrayOfArrays = [NSArray arrayWithObjects: 
          [NSArray arrayWithObjects:....], 
          [NSArray arrayWithObjects:....], 
          [NSArray arrayWithObjects:....], 
          [NSArray arrayWithObjects:....], 
          [NSArray arrayWithObjects:....], 
          [NSArray arrayWithObjects:....], 
          nil]; 
NSPredicate * filter = [NSPredicate predicateWithFormat:@"SUBQUERY(SELF, $a, [email protected] > 42)"]; 
NSArray * filtered = [arrayOfArrays filteredArrayUsingPredicate:filter]; 
//"filtered" is an array of arrays 
//the only arrays in "filtered" will have at least 42 elements each 
+1

Ihr NSPredicate wird nicht kompilieren: gefangen " NSInvalidArgumentException "," Kann die Formatzeichenfolge "SUBQUERY (SELF, $ a, $ a. @ Count> 2) nicht analysieren" " – cfischer

+0

@cfisher Kleinere Korrektur: Das ist ein Laufzeitfehler, kein Kompilierungsfehler. (Nicht versuchen, ein Idiot zu sein.) – sudo

11

Here ist ein Artikel zu diesem Thema mit großer Erklärung und Beispiel.

0

Subquery stellt ein Prädikat (drittes Argument - $x IN %@), die für alle Objekte ausgewertet wird (zweites Argument - $x - es ist wie ein Variablenname in foreach) eine Beziehung (erstes Argument - Bs). Ähnlich wie bei der regulären Abfrage wird eine Liste von Objekten zurückgegeben.

ich an vielen Orten zu sehen, die fast dogmatisch $x verwenden Menschen, aber $object in objects Beziehung auch durchaus Sinn macht (oder $city in cities ...) :)