关于iphone:用于排序和过滤的NSSortDescriptor和NSPredicate

NSSortDescriptor and NSPredicate for sorting and filtering

我有一个tableView,它具有5个可能的数据源,具体取决于标志对象(NSNumber *)dataSourceAssignment。我已经实现了一个NSSortDescriptor,它按(float)confidenceRatingdataSource进行排序。

分配数据源后,我需要能够通过(NSString *)genre过滤dataSource数组。我了解如何使用NSPredicate过滤数组,但是当可以检查5-6个不同的genre字符串时,我无法弄清楚如何有效地执行此操作。

用户可以"检查"多种流派,这些流派基本上应根据选择的流派来切换曲目的显示。我正在考虑在NSUserDefaults *defaults中创建一个看起来像这样的字典:["genre1" = YES,"genre2" = NO,"genre3" = YES ...]

如何使用流派字典设置NSPredicate来过滤数据源,而不使用带有大量条件的巨大if / switch语句。

这是实现NSPredicate之前我拥有的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- (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];
}

您可以将哪些类型的音乐存储到数组中,然后使用谓词。
您还可以在用户选择/取消选择元素时删除/添加元素。

1
2
3
4
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)

使用predicateWithFormat时,可以将有关谓词的正则表达式语句传递给它。该字符串是您可以进行多个谓词的地方,因此可以作为选择不同流派时所做的更改。

例如,您可以具有:predicateWithFormat:predicateString,然后如果用户选择了genre1和genre2,则将predicateString设置为与"SELF beginswith genre1 AND SELF beginswith genre1"相似的东西。尽管一定要仔细检查我使用的正则表达式,但要使它正常运行,您需要的东西要比它好。