【问题标题】:NSFetchRequest to retrieve Every Student's Maximum Test Score for Every Subject in CoreData EntityNSFetchRequest 检索 CoreData 实体中每个科目的每个学生的最高考试分数
【发布时间】:2015-06-17 23:24:24
【问题描述】:

我有一个 CoreData 实体,它在不同长度的比赛中具有多个性能记录。我想在每个比赛中为每个运动员获得最佳表现,然后将结果放在CoreData Table View中。

这是我为实现此目的而想出的技巧。但是,这会干扰我将结果放入 TableView 中,其中比赛距离是部分标题:

- (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
{
MarksFromMeets* results = nil;

NSMutableArray * bestMarks = [[NSMutableArray alloc] init];


NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MarksFromMeets"];

//    NSLog(@"self.athlete.athleteID = %@",self.athlete.athleteID);

request.predicate = [NSPredicate predicateWithFormat:@"(ANY whoRan.athleteID in %@) AND (eventPR > 0)",
                     self.athleteIDsForPredicate];
/* Call the records for selected athletes (PLURAL) */


request.sortDescriptors = [NSArray arrayWithObjects:
                           [NSSortDescriptor sortDescriptorWithKey:@"whoRan.athleteID" ascending:NO],
                           [NSSortDescriptor sortDescriptorWithKey:@"event" ascending:YES],
                           [NSSortDescriptor sortDescriptorWithKey:@"sortMark" ascending:YES],
                           nil];

以下代码块中的代码是我为每个运动员提取最佳表现的地方。

NSArray * allMarks = [self.headToHeadManagedObjectContext executeFetchRequest:request error:nil];

MarksFromMeets* tempMark;

for (MarksFromMeets* athletePRs in allMarks) {

    if (tempMark == nil) {
        tempMark = athletePRs;
    } else {
        if ([athletePRs.whoRan.athleteID isEqualToString:tempMark.whoRan.athleteID]) {
            if ([athletePRs.event isEqualToString:tempMark.event]) {
                if (athletePRs.sortMark < tempMark.sortMark) {
                    tempMark = athletePRs;
                }
            } else {
                [bestMarks addObject:tempMark];
                tempMark = athletePRs;
            }
        } else {
            [bestMarks addObject:tempMark];
            tempMark = athletePRs;
        }
    }
}
if (debug == 1) NSLog(@"bestMarks count: %lu \nallMarks count: %lu", (unsigned long)[bestMarks count], [allMarks count]);

[self setResultsArray:bestMarks];

NSArray bestMarks 有 27 个 NSManagedObjects,而 fetch 请求返回 35 个。

下面的代码是我过去并且仍然希望填充我的 CoreData TableView 的方式。

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                    managedObjectContext:self.headToHeadManagedObjectContext
                                                                      sectionNameKeyPath:@"event"
                                                                            cacheName:nil];

NSError* error = nil;

results = [[self.headToHeadManagedObjectContext executeFetchRequest: request error:&error]objectAtIndex:0];

NSError* requestError = nil;
NSUInteger myCount = [self.headToHeadManagedObjectContext countForFetchRequest:request error:&requestError];
NSLog(@"In %@ and count of results = %lu", NSStringFromClass([self class]),(unsigned long)myCount);
if (!myCount || myCount == 0) {
    NSMutableString* titleText = [NSMutableString stringWithFormat:@"No Records Found"];
    NSMutableString* messageText = [NSMutableString stringWithFormat:@"There were no records found for the %lu athletes selected. Contact ITrackPerfomance using this list of Athlete ID's: %@",  (unsigned long)[self.athleteIDsForPredicate count], self.athleteIDsForPredicate];

    NSString* cancelText = @"Okay";

    [self displayAlertBoxWithTitle:(NSString*)titleText message:(NSString*) messageText cancelButton:(NSString*) cancelText];
}
}

有没有办法用 NSFetchRequest 谓词做到这一点?

或者我可以通过将托管对象放入 NSDictionaries 的 NSArray 中来创建部分,其中每个 NSDictionary 是不同的比赛距离?

感谢您的帮助。如果我完全偏离了正确的道路并且有更有效的方法来实现这一点,我也会很高兴知道这一点!

【问题讨论】:

    标签: ios uitableview core-data nspredicate


    【解决方案1】:

    好的,这就是我想出的。希望这可以帮助其他人: 我根据“类”(在我的例子中是种族)将托管对象解析为 NSMutableArrays。然后我将每个 NSM 数组放入一个 NSMutableDictionary 中,其中索引充当键。这个字典和其中的数组就成为确定节数和节中行数的基础。

    - (void)setupFetchedResultsController // attaches an NSFetchRequest to this UITableViewController
    {
    MarksFromMeets* results = nil;
    
    NSMutableArray * bestMarks = [[NSMutableArray alloc] init];
    NSMutableDictionary * dictionaryOfMarksByRace = [[NSMutableDictionary alloc] init];
    
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MarksFromMeets"];
    
    //    NSLog(@"self.athlete.athleteID = %@",self.athlete.athleteID);
    
    request.predicate = [NSPredicate predicateWithFormat:@"(ANY whoRan.athleteID in %@) AND (eventPR > 0)",
                         self.athleteIDsForPredicate];
    /* Call the records for selected athletes (PLURAL) */
    
    
    request.sortDescriptors = [NSArray arrayWithObjects:
                               [NSSortDescriptor sortDescriptorWithKey:@"event" ascending:YES],
                               [NSSortDescriptor sortDescriptorWithKey:@"whoRan.athleteID" ascending:NO],
                               [NSSortDescriptor sortDescriptorWithKey:@"sortMark" ascending:YES],
                               nil];
    
    
    NSArray * allMarks = [self.headToHeadManagedObjectContext executeFetchRequest:request error:nil];
    
    MarksFromMeets* previousMark;
    
    int i = 0;
    int j = 0;
    for (MarksFromMeets* athletePRs in allMarks) {
        NSArray* sortedMarks;
        if (previousMark == nil) {
            previousMark = athletePRs;
        } else {
            if ([athletePRs.event isEqualToString:previousMark.event]) {
                if ([athletePRs.whoRan.athleteID isEqualToString:previousMark.whoRan.athleteID]) {
                    NSLog(@"athletePRs.%@ = previousMark.%@",athletePRs.sortMark,previousMark.sortMark);
    
    
                    if ([athletePRs.sortMark intValue] < [previousMark.sortMark intValue]) {
                        previousMark = athletePRs;
                        NSLog(@"Should NEVER happen");
                    }
                } else {
                    [bestMarks addObject:previousMark];
                    NSLog(@"Adding %@, %@, %@ to bestMarks for i = %d",previousMark.event, previousMark.markInEvent, previousMark.whoRan.athleteFullName,i);
                    previousMark = athletePRs;
                    NSLog(@"tempMark record now %@",previousMark.whoRan.athleteFullName);
                    if (j == [allMarks count]-1) {
                        [bestMarks addObject:previousMark]; //Now tempMark is last MarksForMeet object
                        sortedMarks = [self sortNSMutableArray:bestMarks];
                        [dictionaryOfMarksByRace setObject:sortedMarks forKey:[NSNumber numberWithInt:i]];
                        bestMarks = [[NSMutableArray alloc] init];
    
                    }
                }
            } else {
                [bestMarks addObject:previousMark];
                previousMark = athletePRs;
                sortedMarks = [self sortNSMutableArray:bestMarks];
                [dictionaryOfMarksByRace setObject:sortedMarks forKey:[NSNumber numberWithInt:i]];
                NSLog(@"Adding %@ to bestMarks for i = %d",previousMark.event,i);
                bestMarks = [[NSMutableArray alloc] init];
                // reallocate bestMarks to ensure values in NSMutableDictionary are unique
                i++;
                if (j == [allMarks count]-1) {
                    [bestMarks addObject:previousMark];
                    sortedMarks = [self sortNSMutableArray:bestMarks];
                    [dictionaryOfMarksByRace setObject:sortedMarks forKey:[NSNumber numberWithInt:i]];
                    bestMarks = [[NSMutableArray alloc] init];
                    // reallocate bestMarks to ensure values in NSMutableDictionary are unique
                }
            }
        }
        j++;
    }
    
    
    [self setResultsDictionary:dictionaryOfMarksByRace];
    
    }
    

    过滤数据后不得不采取措施。可能有一种更有效的方法,但这种蛮力方法有效,因为我在这种方法中从 Core Data 中提取的记录相对较少。

    【讨论】:

      猜你喜欢
      • 2022-10-04
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多