Reputation: 1820
I have a tableView that has 5 different possible datasources depending on a flag object (NSNumber *)dataSourceAssignment
. I've implemented an NSSortDescriptor
that sorts dataSource
by a (float)confidenceRating
.
After the datasource is assigned, I need to be able to filter the dataSource array by a (NSString *)genre
. I understand how to use NSPredicate
to filter my array, but I can't figure out how to do it efficiently when there are 5-6 different genre
strings that could be checked.
The user is able "check" multiple genres that should basically toggle the display of tracks according to which genres are selected. I was thinking of creating a dictionary in NSUserDefaults *defaults
that would look something like this: ["genre1" = YES, "genre2" = NO, "genre3" = YES ...]
.
How can I set up NSPredicate
to filter datasource using the genre dictionary without using a huge if/switch statement with loads of conditions.
Here is the code I have before a NSPredicate
is implemented:
- (void)assignDataSource
{
switch (dataSourceAssignment.intValue) {
case 0: dataSource = [NSMutableArray arrayWithArray:tracksArray]; break;
case 1: dataSource = [NSMutableArray arrayWithArray:favoriteTracks]; break;
case 2: dataSource = [NSMutableArray arrayWithArray:topTracksOfTheWeek]; break;
case 3: dataSource = [NSMutableArray arrayWithArray:topTracksOfTheMonth]; break;
case 4: dataSource = [NSMutableArray arrayWithArray:topTracksOfTheYear]; break;
default: break;
}
if (dataSourceAssignment.intValue >= 2) {
NSSortDescriptor *avgRatingSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"confidenceRating" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObjects:avgRatingSortDescriptor, nil];
NSArray *sortedArray = [dataSource sortedArrayUsingDescriptors:sortDescriptors];
dataSource = [NSMutableArray arrayWithArray:sortedArray];
}
Upvotes: 0
Views: 3010
Reputation: 1318
You can store which genres were selected into array and then use predicate. You can also remove/add elements when user select/deselect elements.
NSArray *selectedGenresByUser = [NSArray arrayWithObjects:@"genre1",@"genre2", nil];
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"genre in $SELECTED_GENRES"];
predicate = [predicate predicateWithSubstitutionVariables:[NSDictionary dictionaryWithObject:[NSArray arrayWithArray:selectedGenresByUser] forKey:@"SELECTED_GENRES"]];
//then use predicate to filter datasource array( maby you can store all elements in one array)
Upvotes: 1
Reputation: 1169
When you use predicateWithFormat
, you can pass it a regular expression statement about the predicate. That string is where you can do multiple predicates, and so that can be what you alter when different genres are selected.
For example, you can have: predicateWithFormat:predicateString
, and then have predicateString
set to be something along the lines of "SELF beginswith genre1 AND SELF beginswith genre1"
if the user has selected genre1 and genre2. Though definitely doublecheck that regex I used, cause you need something better than that for it to work well.
Upvotes: 1