2015-04-24 43 views
0

我有一個tableview中,其頭部被存儲在一個mutablearray,數組看起來像排序NSMutableArray裏有兩個特殊的鍵

(2005 fall, 2005 spring, 2007 summer...) 

當我輸出的tableview,我想在時間升序標題顯示。

2005 spring 
2005 fall 
2007 summer 

我這裏使用的代碼:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 
    [self.sectionKeys sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; 
    NSString *key = [self.sectionKeys objectAtIndex:section]; 
    return key; 
} 

它正常工作與year。但是,fall之前springsummer由於字母表原因,請問該怎麼辦?

+0

我不明白。按字母順序,「秋天」應該在「春天」之前。不按「季節」順序「邏輯」。 – Larme

+0

那麼你最近的問題是什麼,如果年份同樣按名稱降序? –

+0

你想要一個自定義排序,因此你不能使用一個簡單的'sortUsingSelector:'調用。編寫你自己的比較器並使用它。 – rmaddy

回答

0

所以你有一個與部分鍵的數組。但是這些部分並不是按照數組的順序排列的,他們需要進行排序。您會注意到cellForRowAtIndexPath:需要完全相同的信息。所以在這個地方排序是錯誤的。

我該怎麼處理這個問題:我有一個屬性「unsortedSectionKeys」和一個屬性「sortedSectionKeys」。 sortedSectionKeys有一個getter,它檢查nil,如果它是零,則存儲unsortedSectionKeys的已排序副本。每當unsortedSectionKeys改變,你只需將sortedSectionKeys設置爲零。 (這解決了至少一些問題)。

爲了您的排序,您需要編寫正確的代碼。使用(void)sortUsingComparator:(NSComparator)cmptr來排序一個可變或 - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr來獲取一個數組的排序副本。

例子:

[self.sectionKeys sortArrayUsingComparator:^NSComparisonResult(NSString* obj1, NSString* obj2) { 
    NSInteger year1 = obj1.integerValue; 
    NSInteger year2 = obj2.integerValue; 
    if (year1 < year2) return NSOrderedAscending; 
    if (year1 > year2) return NSOrderedDescending; 

    NSInteger season1 = 0; 
    if ([obj1 rangeOfString:@"spring" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season1 = 1; 
    if ([obj1 rangeOfString:@"summer" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season1 = 2; 
    if ([obj1 rangeOfString:@"fall" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season1 = 3; 
    if ([obj1 rangeOfString:@"winter" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season1 = 4; 

    NSInteger season2 = 0; 
    if ([obj2 rangeOfString:@"spring" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season2 = 1; 
    if ([obj2 rangeOfString:@"summer" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season2 = 2; 
    if ([obj2 rangeOfString:@"fall" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season2 = 3; 
    if ([obj2 rangeOfString:@"winter" options:NSCaseInsensitiveSearch].location != NSNotFound) 
     season2 = 4; 

    if (season1 < season2) return NSOrderedAscending; 
    if (season1 > season2) return NSOrderedDescending; 
    return NSOrderedSame; 
}]; 

你的決定,如果冬季是一年中的第一個或最後一個賽季,因爲通常它是十二月到二月。

+0

非常感謝,它正在工作。 – user4441082

+2

我建議將幾個'if'語句改爲'if/else'語句。這將是更有效率。此外,使用一系列季節名稱(如其他答案)可以大大縮小代碼,避免潛在的錯誤和錯誤。 – rmaddy

2

使用自定義比較得到一個自定義排序順序:

NSMutableArray *array = [@[ @"2005 fall", @"2005 spring", @"2007 summer" ] mutableCopy]; 

NSArray *seasons = @[ @"spring", @"summer", @"fall", @"winter" ]; 

[array sortUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) { 
    NSArray *parts1 = [str1 componentsSeparatedByString:@" "]; 
    NSArray *parts2 = [str1 componentsSeparatedByString:@" "]; 

    NSString *year1 = parts1[0]; 
    NSString *year2 = parts2[0]; 
    NSComparisonResult yearRes = [year1 compare:year2 options:NSNumericSearch]; 
    if (yearRes == NSOrderedSame) { 
     NSString *season1 = parts1[1]; 
     NSString *season2 = parts2[1]; 

     NSUInteger index1 = [seasons indexOfObject:season1]; 
     NSUInteger index2 = [seasons indexOfObject:season2]; 

     if (index1 < index2) { 
      return NSOrderedAscending; 
     } else if (index1 > index2) { 
      return NSOrderedDescending; 
     } else { 
      return NSOrderedSame; 
     } 
    } else { 
     return yearRes; 
    } 
}]; 

注 - 我可能具有NSOrderedAscendingNSOrderedDescending倒退。如果在同一年的季節類型以相反的順序出現,請交換它們。

+0

非常感謝您的回覆。 – user4441082

2

你需要查找機制來定義季節

NSArray *seasons = @[@"spring", @"summer", @"fall", @"winter"]; 

NSArray *strings = @[@"2005 fall",@"2007 spring", @"2005 spring", @"2007 winter", @"2005 winter"]; 
strings = [strings sortedArrayUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) { 
    NSArray *string1Comps = [obj1 componentsSeparatedByString:@" "]; 
    NSArray *string2Comps = [obj2 componentsSeparatedByString:@" "]; 

    NSComparisonResult compareYearResult = [@([string1Comps[0] integerValue]) compare:@([string2Comps[0] integerValue]) ]; 
    if (compareYearResult == NSOrderedSame) { 
     return [@([seasons indexOfObject:string1Comps[1]]) compare:@([seasons indexOfObject:string2Comps[1]])]; 
    } 
    return compareYearResult; 
}]; 

結果的排序

(
    2005 spring, 
    2005 fall, 
    2005 winter, 
    2007 spring, 
    2007 winter 
) 

另一個查找機制可能是一個塊

NSNumber* (^lookUpSeason)(NSString *) = ^(NSString *seasonname){ 
    static NSArray *seasons; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     seasons = @[@"spring", @"summer", @"fall", @"winter"]; 
    }); 
    return @([seasons indexOfObject:seasonname]); 
}; 

這看起來有點麻煩,但使用時會增加可讀性。

return [@([seasons indexOfObject:string1Comps[1]]) compare:@([seasons indexOfObject:string2Comps[1]])]; 

成爲

return [lookUpSeason(string1Comps[1]) compare:lookUpSeason(string2Comps[1])]; 

在這兩種情況下,你也可以給查找代碼到比較塊,這會給你機會與在其他地方查找刪除相同的比較。

,如:

NSArray *strings = @[@"2005 fall", @"2007 spring", @"2005 spring", @"2007 winter", @"2005 winter", @"2005 summer", @"2000 hhh"]; 

NSComparisonResult (^yearAndSeasonComparator)(id,id) = ^NSComparisonResult(NSString *obj1, NSString *obj2) { 
    NSNumber* (^lookUpSeason)(NSString *) = ^(NSString *seasonname){ 
     static NSArray *seasons; 
     static dispatch_once_t onceToken; 
     dispatch_once(&onceToken, ^{ 
      seasons = @[@"spring", @"summer", @"fall", @"winter"]; 
     }); 
     return @([seasons indexOfObject:seasonname]); 
    }; 

    NSArray *string1Comps = [obj1 componentsSeparatedByString:@" "]; 
    NSArray *string2Comps = [obj2 componentsSeparatedByString:@" "]; 

    NSComparisonResult compareYearResult = [@([string1Comps[0] integerValue]) compare:@([string2Comps[0] integerValue]) ]; 
    if (compareYearResult == NSOrderedSame) { 
     return [lookUpSeason(string1Comps[1]) compare:lookUpSeason(string2Comps[1])]; 
    } 
    return compareYearResult; 
}; 

strings = [strings sortedArrayUsingComparator:yearAndSeasonComparator]; 

分配給yearAndSeasonComparator塊現在可以在其他地方,將相似的字符串進行排序被重用。

+2

偉大的思想家都認爲:) – rmaddy