views:

65

answers:

2

I am working on my first iPhone application and I've hit a wall. I'm trying to develop a 'statistics' page for a three entity relationship. My entities are the following:

Department - Name, Address, Building, etc. People - Name, Gender (BOOL), Phone, etc

If I have fetched a specific department how do I filter those results and only return people that are Male (Gender == 0)?

If I do

NSLog(@"%d", [department.people count]);

I get the correct number of people in that department so I know I'm in the neighborhood. I know I could re-fetch and modify the predicate each time but with 20+ stats in my app that seems inefficient. Thanks for any advice!

A: 

You don't need to refetch:

NSPredicate* pred = [NSPredicate predicateWithFormat:@"gender == NO"];
NSUInteger count = [[department.people filteredArrayUsingPredicate:pred] count];
NSLog(@"%lu", (unsigned long)count);

Somehow gender==NO still looks strange though ;)

If copying is too expensive, you could use enumerators instead. E.g.:

NSUInteger CountIf(NSEnumerator* en, NSPredicate* pred) {
    NSUInteger count = 0;
    id obj;
    while (obj = [en nextObject]) {
        if([pred evaluateWithObject:obj]) 
            ++count;
    }
    return count;
}

NSUInteger count = CountIf([department.people objectEnumerator], predicate));

... though this would be ideally moved to a suitable category as say countOfObjectsMatchingPredicate:.

Georg Fritzsche
Georg, thanks so much. Perfect.
Gary
A: 

You could create NSPredicates representing your different filters and use NSSet's filteredSetWithPredicate: method. The count method will give you the number of entities matching the predicate. This isn't terribly efficient because you're creating a new set for each calculation, but it may be significantly faster than fetching each time.

warrenm