CoreData + geschickt Objekte ermitteln

  • CoreData + geschickt Objekte ermitteln

    Hallo,

    ich habe eine CoreData Anwendung vor mir liegen (Model siehe Anhang).

    Kurze Beschreibung:

    * Eine Firma hat viele Mitarbeiter, jeder Mitarbeiter hat viele Computer.
    * Ein Computer hat ein Attribut (mac) vom Typ BOOL. Ist mac == YES, dann ist der Computer ein Mac - falls mac == NO, dann ist der Computer kein Mac.

    Aufgabe:

    Innerhalb eines "Firma" Objektes möchte ich möglichst einfach alle Computer ermitteln, bei denen es sich um ein Mac handelt (where mitarbeiter.computers.mac == YES).

    Momentan mach ich das recht umständlich in einer Methode in dem Firmenobjekt:

    * Alle Mitarbeiter der Firma ermitteln (valueForKeyPath:@"mitarbeiter")
    * Durch die Mitarbeiter iterieren und deren Computer ermitteln, deren mac Attribut == YES ist. Das erledige ich mit einem NSPredicate.

    Das geht doch bestimmt besser. Ich dachte da an die geliebten KeyPath Operatoren. Meine Versuche scheiterten allerdings alle.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • RE: CoreData + geschickt Objekte ermitteln

    So geht das nicht, weil du zwei 1:n-Beziehungen hast. Beim zweiten Key des Pfades flippt er aus.

    Du kannst in einem Predicate sagen, dass nur diejenigen Objekte gewählt werden sollen, bei denen mindestens ein verwiesenes Objekt eine Bedingung erfüllt. Man nennt solchhe "Zusammmenzieher" Aggregates. In deinem Falle müsste das Prädikat auf das Mitarbeiter-Array wie folgt lauten:

    Quellcode

    1. ANY computers.mac == YES


    developer.apple.com/documentat…doc/uid/TP40001795-215891

    Also als Code jetzt trocken programmiert:

    Quellcode

    1. NSPredicate* predicate = [NSPredicate predicateWithFormat:@"ANY computers.mac == YES"];
    2. NSArray* employees = [[theCompany employees] allObjects];
    3. NSArray* employeesWithMac = [employees filteredArrayUsingPredicate:predicate];
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Ah, verstehe. Ne, das geht meines Wissens nicht von Hause aus. Du kannst natürlich einen Fetch auf die Computer machen und dann den Pfad zur Firma zurückverfolgen. Spätestens, wenn du viele Firmen hast, wirst du das Geswappe aber nicht wollen.

    Dann iteriere doch so, dass du eine sinnvolle Funktion hast, die man ohnehin braucht, nämmlich in dem du zunächst alle Sets vereinigst und dann darauf das Predicate anwendest:

    Quellcode

    1. @implementation NSSet( SubsetAggregation )
    2. - (void)aggregateToSuperset:(NSDictionary*)map {
    3. NSSet* subset = [self valueForKeyPath:[map oebjctForKey:@"keyPath"]];
    4. [[map objectForKey:@"superset"] unionSet:subset];
    5. }
    6. - (NSSet*)aggreggateSubsetsWithKeyPath:(NSString*)keyPath {
    7. NSMutableSet* superset = [NSMutableSet set];
    8. NSDictionary* map = [NSDictionary dictionaryWithObjectsAndKeys:superset, @"superset", keyPath, @"keyPath", nil];
    9. [mutableSet makeObjectsPerformSelector:@selector( aggregateToSuperset: ) withObject:map];
    10. return superset;
    11. }
    12. @end
    Alles anzeigen

    Dann hast du es im Hauptcode übersichtlich und so ein Dingens benötigt man ohnehin immer wieder:

    Quellcode

    1. NSSet* employees = [self valueForKey:@"employees"];
    2. NSSet* computers = [employees aggregateSubsetsWithKeyPath:@"computers"]
    3. // Und dann einfach auf mac = YES testen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Zeile 9:

    Quellcode

    1. [mutableSet makeObjectsPerformSelector:@selector( aggregateToSuperset: ) withObject:map];
    Das mutableSet ist nicht erklärt, soll anscheinend 'superset' sein.
    Gute Idee!
    I would be embarrassed if they did not spy on me.