从数组中获取独特的年份

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.

轻松获取特定年份(或之后)的日期