从数组中获取独特的年份
Get unique years from array
我有以下结构的数组,我想从该数组中获取唯一年份的数组。
我已经使用 for 循环获得了所需的输出,但可以建议更好的方法来获得所需的输出。
[
{ date = "2015-12-19 11:56:51 +0000"; },
{ date = "2015-12-19 11:56:51 +0000"; },
{ date = "2015-12-19 11:56:52 +0000"; },
{ date = "2013-11-19 11:56:52 +0000"; },
{ date = "2013-09-20 11:56:52 +0000"; },
{ date = "2014-12-07 11:56:58 +0000"; },
{ date = "2015-12-19 11:57:03 +0000"; },
{ date = "2012-08-08 11:57:07 +0000"; },
{ date = "2010-08-19 11:57:20 +0000"; }
]
对于上面的数组输出数组应该是
["2015", "2014", "2013", "2012", "2010"]
这是我现在正在使用的代码:
NSMutableSet *setDate = [NSMutableSet set];
for (NSDictionary *dicData in arrayDates) {
NSString *strDate = [[dicData valueForKeyPath:@"date"] substringToIndex:4];
// my date format always same so no issue with substring
[setDate addObject:strDate];
}
您需要以一种或另一种方式遍历数组的元素。它可以是 "for" 循环、"foreach" 循环或 enumerateObjectsUsingBlock:
,但循环将在那里。
由于年份是相对较小的整数,收集输出的一种方法是使用 NSIndexSet
。这个集合很快,而且总是排好序。这是一个使用 enumerateObjectsUsingBlock:
的解决方案
NSMutableIndexSet *res = [NSMutableIndexSet indexSet];
[myDates enumerateObjectsUsingBlock:^(id d, NSUInteger index, BOOL *stop){
NSDateComponents *dc = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:d];
[res addIndex:[dc year]];
}];
现在 res
包含从您 NSArray
中的日期开始的唯一年份。
与 dasblinkenlight 在他的回答中所说的相反,这可以在没有循环的情况下完成(好吧,至少不用明确地编写循环 ;-)。
您可以在 NSDate
上添加一个类别,其中包含 returns 年:
的方法
@interface NSDate (Year)
- (NSInteger)my_year;
@end
@implementation NSDate (Year)
- (NSInteger)my_year
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:self];
return components.year;
}
@end
那么您可以使用键值编码的强大功能:
//look, ma! no loops! no set!
NSArray *uniqueYears = [dates valueForKeyPath:@"@distinctUnionOfObjects.my_year"];
当然,仅仅为了这个目的而编写类别是一种矫枉过正的做法。但是方法 my_year
可以在其他可以提供 keypath 的地方重用。例如,您可以使用 NSPredicate
.
轻松获取特定年份(或之后)的日期
我有以下结构的数组,我想从该数组中获取唯一年份的数组。
我已经使用 for 循环获得了所需的输出,但可以建议更好的方法来获得所需的输出。
[
{ date = "2015-12-19 11:56:51 +0000"; },
{ date = "2015-12-19 11:56:51 +0000"; },
{ date = "2015-12-19 11:56:52 +0000"; },
{ date = "2013-11-19 11:56:52 +0000"; },
{ date = "2013-09-20 11:56:52 +0000"; },
{ date = "2014-12-07 11:56:58 +0000"; },
{ date = "2015-12-19 11:57:03 +0000"; },
{ date = "2012-08-08 11:57:07 +0000"; },
{ date = "2010-08-19 11:57:20 +0000"; }
]
对于上面的数组输出数组应该是 ["2015", "2014", "2013", "2012", "2010"]
这是我现在正在使用的代码:
NSMutableSet *setDate = [NSMutableSet set];
for (NSDictionary *dicData in arrayDates) {
NSString *strDate = [[dicData valueForKeyPath:@"date"] substringToIndex:4];
// my date format always same so no issue with substring
[setDate addObject:strDate];
}
您需要以一种或另一种方式遍历数组的元素。它可以是 "for" 循环、"foreach" 循环或 enumerateObjectsUsingBlock:
,但循环将在那里。
由于年份是相对较小的整数,收集输出的一种方法是使用 NSIndexSet
。这个集合很快,而且总是排好序。这是一个使用 enumerateObjectsUsingBlock:
NSMutableIndexSet *res = [NSMutableIndexSet indexSet];
[myDates enumerateObjectsUsingBlock:^(id d, NSUInteger index, BOOL *stop){
NSDateComponents *dc = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:d];
[res addIndex:[dc year]];
}];
现在 res
包含从您 NSArray
中的日期开始的唯一年份。
与 dasblinkenlight 在他的回答中所说的相反,这可以在没有循环的情况下完成(好吧,至少不用明确地编写循环 ;-)。
您可以在 NSDate
上添加一个类别,其中包含 returns 年:
@interface NSDate (Year)
- (NSInteger)my_year;
@end
@implementation NSDate (Year)
- (NSInteger)my_year
{
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:self];
return components.year;
}
@end
那么您可以使用键值编码的强大功能:
//look, ma! no loops! no set!
NSArray *uniqueYears = [dates valueForKeyPath:@"@distinctUnionOfObjects.my_year"];
当然,仅仅为了这个目的而编写类别是一种矫枉过正的做法。但是方法 my_year
可以在其他可以提供 keypath 的地方重用。例如,您可以使用 NSPredicate
.