views:

68

answers:

3

Hello i have a maybe easy question but i cant handle it yet.

  • I have a Modelclass 'Location' which holds an Array with Category ID's (12, 23, 56).
  • Then i have an Array with all available Category ID's (1,2,3,4,5,6,7,...)
  • All this Categories have an ID are shown in a TableView and are able to select or not.
  • I show a punch of Markers on a MapView (Annotation Class is Location) which should be shown based on the selection of the filters in the mentioned Filter TableView.

I need to implement a "Filter by Category" function which removes all markers and add them again but just based on the selection in the list.

So i need to compare the array with the filter-id's in the Location Model with the Array with all the Filter-ID's in the TableView. i used the following function for this:

for (Location *currLocation in arrListOfLocationsNearby) {

for (NSString *currKatId in currLocation.arrKatIds) {

NSInteger intCurrKatId = [currKatId integerValue];
NSLog(@"Current KatId %@ id: %d \n", currLocation.strAdr, intCurrKatId);

for (Filter *currFilter in [SDM getSharedDataManager].arrListOfFilterOptions) {

 if (currFilter.isSelected) {

  NSInteger intCurrFilterId = [currFilter.strAtt_id intValue];
  NSLog(@"Current Filter %@ id: %d \n", currFilter.strAtt_text, intCurrFilterId);

  if ([currKatId intValue] == [currFilter.strAtt_id intValue]) {
   currLocation.isVisible = YES;
  }else {
   currLocation.isVisible = NO;
  }
 }
}

} }

I know this will be the most ineffective way to loop through everything. I want to use somehow NSPredicate for this but i never used them before and i can't find examples for my problem.

Any Hints from you guys?

regards m.

A: 

Try having a string representation of each test:

NSArray *arrayOfPredicateStrings = ;// array of all tests, probably [SDM sharedDataManager].arrListOfFilterOptions

NSPredicate *enabled = [NSPredicate predicateWithFormat:@"isSelected == true"];

NSArray *arrayOfEnabledPredicateStrings = 
        [arrayOfPredicateStrings filteredArrayUsingPredicate:enabled];

NSMutableString *formatString;
BOOL firstTime = YES;
for (NSString *string in arrayOfEnabledPredicateStrings) { 
    // Concatinate strings with OR inbetween
    if (firstTime) {
        firstTime = NO;
        formatString = [string mutableCopy];
    } else {
        [formatString appendFormat:@" OR %@", string]; 
    }
} // formatString should look something like @"ivar1 >= 1 OR ivar2 == true OR ivar3 != \"Hello, World\""
NSPredicate *predicate = [NSPredicate predicateWithFormat:string];

NSArray *arrListOfLocationsNearby; // assume already filled

NSArray *suitableNearbyLocations = 
        [arrListOfLocationsNearby filteredArrayUsingPrediacate:predicate];

If a CoreData data store is behind your SDM class, just create a fetch request like so:

NSPredicate *predicate = ;// get the predicate as above
NSManagedObjectContext  *context = ;// a managed object context
NSEntityDescription *entity = 
        [NSEntityDescription entityForName:@"entityName" inManagedObjectContext:context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
request.predicate = predicate;

NSError *error;
NSArray *results = [context executeFetchRequest:request error:&error];
[request release];

Predicate format syntax can be found here and usage can be found here

cool_me5000
A: 

So each "Location" object has many "categoryIDs"? And you want to show any of the Location objects that have a categoryID inside your "arrayOfEnabledCategoryIDs"?

Assuming that you have a Location entity and a CategoryID entity, and that there's a many-to-many relationship (locations <<--->> categories) between them, you can do this:

NSArray * arrayOfEnabledCategoryIDs = ...; //these are the categories to display
NSFetchRequest * f = [[NSFetchRequest alloc] init];
[f setEntity:theEntityDescriptionForLocationObjects];
[f setPredicate:[NSPredicate predicateWithFormat:@"ANY categories.categoryID IN %@", arrayOfEnabledCategoryIDs]];
Dave DeLong
A: 

If you are familiar with ActiveRecord from Ruby On Rails. I've been using a great library called activerecord+fetching+for+core you can find more about it here http://github.com/magicalpanda/activerecord-fetching-for-core-data

NSArray *departments = [NSArray arrayWithObjects:dept1, dept2, ..., nil];
NSPredicate *peopleFilter = [NSPredicate predicateWithFormat:@"Department IN %@", departments];

NSArray *people = [Person findAllWithPredicate:peopleFilter];

It has really cleaned up my code.

jarrold