如何在NSDate中使用NSPredicate进行分组 – 需要创build多个UITableView部分

也可以看看

核心数据按date分类FetchedResultsController

有没有办法按date从CoreData实体中分组对象,并使用它们在UITableView控件上创build多个部分?

实质上,我需要一些等同于下面的伪SQL,其中my_group_criteria()将所有testing按天分组:

SELECT * FROM tests GROUP BY my_group_criteria(date) 

作为一个例子,查询将下列行分成3个独立的部分:

 [test1 | 2013-03-18 15.30.22] [test2 | 2013-03-18 14.30.22] [test3 | 2013-03-18 13.30.22] [test4 | 2013-03-17 18.30.22] [test5 | 2013-03-17 19.30.22] [test6 | 2013-03-15 20.30.22] 

正如已经在2中所回答的那样,NSPredicate不是用于分组实体,所以这可能不是要走的路。

鉴于此,我如何根据一些类似于SQL GROUP BY的标准在UITableView中创build多个部分?

我想避免直接访问SQL-lite数据库,如果可能的话。

相关问题1: NSPredicate:按NSDate属性过滤对象

相关问题2: NSPredicate类似于SQL的GROUP BY

您可以根据需要从Apple Developer Library中修改DateSectionTitles示例项目。

首先,您必须修改瞬态sectionIdentifier属性的访问器函数,以根据年份+月份+date(而不是年+月份)创build节标识符:

 - (NSString *)sectionIdentifier { // Create and cache the section identifier on demand. [self willAccessValueForKey:@"sectionIdentifier"]; NSString *tmp = [self primitiveSectionIdentifier]; [self didAccessValueForKey:@"sectionIdentifier"]; if (!tmp) { /* Sections are organized by month and year. Create the section identifier as a string representing the number (year * 10000 + month * 100 + day); this way they will be correctly ordered chronologically regardless of the actual name of the month. */ NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[self timeStamp]]; tmp = [NSString stringWithFormat:@"%d", [components year] * 10000 + [components month] * 100 + [components day]]; [self setPrimitiveSectionIdentifier:tmp]; } return tmp; } 

其次, titleForHeaderInSection委托方法必须改变,但想法是相同的:从节标识符提取年,月和日,并从中创build一个标题标题string:

 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { id <NSFetchedResultsSectionInfo> theSection = [[fetchedResultsController sections] objectAtIndex:section]; NSInteger numericSection = [[theSection name] integerValue]; NSInteger year = numericSection / 10000; NSInteger month = (numericSection / 100) % 100; NSInteger day = numericSection % 100; // Create header title YYYY-MM-DD (as an example): NSString *titleString = [NSString stringWithFormat:@"%d-%d-%d", year, month, day]; return titleString; } 

假设这个想法是将对象数组分组成一个对象数组数组,我会采取的方法是,首先find可能的date值(或任何你想分组),然后实际分类。

 NSArray *values = ...; NSArray *sorting = [values valueForKey:@"@distinctUnionOfObject.propertyToGroupBy"]; NSUInteger sectionCount = [sorting count]; NSMutableArray *sections = [NSMutableArray arrayWithCapacity:sectionCount]; for (int i = 0; i < sectionCount; i++) [sections addObject:[NSMutableArray array]]; [values enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // Figure out the section for this object NSUInteger section = [sorting indexOfObject:obj.propertyToGroupBy]; [[sections objectAtIndex:section] addObject:obj]; }]; // sections will contain as many sections as there were unique values // each of those values is an array containing values that matched the criteria 

这可能会被优化,但从我的头顶来看,似乎符合法案。

编辑:再次通过问题后,propertyToGroupBy将不得不规范化的价值观,即删除date的时间组件,作为分组是由唯一值(即比较是基于isEqual 🙂