我有一个tableview,它的标题存储在mutablearray中,数组看起来像
(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
出现在spring
和summer
之前,因为字母统计,请该怎么做才能解决它?
答案 0 :(得分: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;
}
}];
注意 - 我可能会向后NSOrderedAscending
和NSOrderedDescending
。如果同一年的季节以相反的顺序出现,则交换它们。
答案 1 :(得分: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 :(得分:0)
所以你有一个带分区键的数组。但是这些部分不是数组的顺序,它们需要进行排序。您会注意到cellForRowAtIndexPath:需要完全相同的信息。所以在这个地方排序是错误的。
我要做的是:我有一个属性“unsortedSectionKeys”和一个属性“sortedSectionKeys”。 sortedSectionKeys有一个getter,它检查nil并存储unsortedSectionKeys的已排序副本(如果它是nil)。每当unsortedSectionKeys发生变化时,您只需将sortedSectionKeys设置为nil即可。 (这解决了至少一些问题)。
对于排序,您需要编写正确的代码。使用(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;
}];
您决定冬季是一年中的第一季度还是最后一季,因为通常是12月到2月。