以一对多关系按最新优先对自定义子对象数组进行排序

Sort an array of custom sub-objects in a one-to-many relationship by newest first

我正在尝试对数组进行排序,以便最新的位于顶部。

我遇到的问题是我正在对一对多关系进行排序,但使用比较似乎无法对它进行排序。

该数组是已完成航班的列表。

NSFetchRequest *fr = [[NSFetchRequest alloc] initWithEntityName:[self entityName]];
    fr.predicate = [NSPredicate predicateWithFormat:@"(acceptedDate != nil || booked == %@ || ANY legs.flight != nil) && ANY legs.departureDate <= %@", @YES, [NSDate date]];

    NSArray *results = [context executeFetchRequest:fr error:nil];

    //Check BOTH legs have completed        
    NSDate *now = [NSDate date];
    NSMutableArray *filtered = [NSMutableArray array];

    for (Quote *quote in results) {
        if ([quote.legs count] > 1) {
            BOOL completed = YES;
            for (QuoteLeg *leg in quote.legs) {
                if ([leg.departureDate compare:now] == NSOrderedDescending) {
                    completed = NO;
                }
            }                
            if (completed) {
                [filtered addObject:quote];
            }
        }
        else {
            [filtered addObject:quote];
        }
    }

    // Try to sort the array
    [filtered sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult(Quote *quote1, Quote *quote2){
       QuoteLeg *leg1 = [[quote1.legs allObjects] firstObject];
       QuoteLeg *leg2 = [[quote2.legs allObjects] firstObject];

       return [leg1.departureDate compare:leg2.departureDate];
    }];

    // Sort filtered by date
    for (Quote *q in filtered) {
        QuoteLeg *leg = [[q.legs allObjects] firstObject];
        NSLog(@"date = %@", leg.departureDate);
    }

这总是输出

date = 2015-01-20 11:00:00 +0000
date = 2015-01-23 12:00:00 +0000
date = 2015-01-29 12:00:00 +0000
date = 2015-01-30 10:40:00 +0000
date = 2015-01-30 10:40:00 +0000
date = 2015-01-29 09:00:00 +0000
date = 2015-01-26 10:00:00 +0000

我需要先确保日期是最新的。

还有什么我可以做的吗?

- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr

方法 return 结果为 NSArray,它不会对您的 NSMutableArray 进行排序。尝试这样做

filtered = [filtered sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult(Quote *quote1, Quote *quote2){
       QuoteLeg *leg1 = [[quote1.legs allObjects] firstObject];
       QuoteLeg *leg2 = [[quote2.legs allObjects] firstObject];

        return [leg1.departureDate compare:leg2.departureDate];
            }];

我想我有答案了。我尝试在没有任何键的情况下将 NSSortDescriptor 包裹起来,结果似乎符合我要求的顺序;

        // Filtered is a NSMutableArray
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:nil ascending:NO
                                                                      comparator:^NSComparisonResult(VICQuote *quote1, VICQuote *quote2){
                                                                          VICQuoteLeg *leg1 = [[quote1.legs allObjects] firstObject];
                                                                          VICQuoteLeg *leg2 = [[quote2.legs allObjects] firstObject];

                                                                        return [leg1.departureDate compare:leg2.departureDate];
                                                                      }];
        [filtered sortUsingDescriptors:@[sortDescriptor]];

        NSArray *finalResults = [NSArray arrayWithArray:filtered];

        // Output them
        for (VICQuote *q in finalResults) {
            VICQuoteLeg *leg = [[q.legs allObjects] firstObject];
            NSLog(@"date = %@", leg.departureDate);
        }

结果:

date = 2015-01-31 10:35:00 +0000
date = 2015-01-30 09:40:00 +0000
date = 2015-01-29 12:00:00 +0000
date = 2015-01-29 09:00:00 +0000
date = 2015-01-28 11:00:00 +0000
date = 2015-01-23 12:00:00 +0000
date = 2015-01-20 11:00:00 +0000