Objective c 按小时、天、周、月、年对数据进行聚类目标c
我有一个属性为time和count的Stat对象。我有一个(按时间排序)每小时都会出现的这些对象的列表。我想聚集起来展示一下。 在objective c中是否有一种按时间对数据进行聚类的好方法?还是一个比下面的幼稚算法更好的算法 这是一个每周做一次的例子。其他的都是类似的,但是您可以更改日期组件Objective c 按小时、天、周、月、年对数据进行聚类目标c,objective-c,nsdate,nsdatecomponents,Objective C,Nsdate,Nsdatecomponents,我有一个属性为time和count的Stat对象。我有一个(按时间排序)每小时都会出现的这些对象的列表。我想聚集起来展示一下。 在objective c中是否有一种按时间对数据进行聚类的好方法?还是一个比下面的幼稚算法更好的算法 这是一个每周做一次的例子。其他的都是类似的,但是您可以更改日期组件 -(void) makeWeeklyData{ Stat *prev = self.hourlyData[0]; NSInteger sum = 0; NSMutableArr
-(void) makeWeeklyData{
Stat *prev = self.hourlyData[0];
NSInteger sum = 0;
NSMutableArray *weeklyData = [NSMutableArray array];
for (CSInstallStat *data in self.hourlyData) {
NSDateComponents *itemComps = [[NSCalendar currentCalendar] components:kCFCalendarUnitWeekOfYear | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:data.time];
[itemComps setCalendar:[NSCalendar currentCalendar]];
NSDateComponents *currComps = [[NSCalendar currentCalendar] components:kCFCalendarUnitWeekOfYear | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:prev.time];
[currComps setCalendar:[NSCalendar currentCalendar]];
if ([itemComps weekOfYear] == [currComps weekOfYear] && [itemComps month] == [currComps month] && [itemComps year] == [currComps year]) {//Same Week
sum += data.count;
} else if([itemComps weekOfYear] >= [currComps weekOfYear] && [itemComps month] == [currComps month] && [itemComps year] == [currComps year]) { //Next Week
Stat *stat = [[CSInstallStat alloc] init];
stat.time = [currComps date];
stat.count = sum;
stat.timeAccuracy = ENUMWeekly;
[weeklyData addObject:stat];
sum = 0;
sum += data.count;
prev = data;
} else {
prev = data;
}
}
self.weeklyData = weeklyData;
}
如果我正在实现这种系统,我倾向于在对象进入时维护统计数据。所以,假设我们有一系列的“每周数据”,为了论证起见,我们想保留52周的数据。在类中,声明成员变量:
NSCalendar *gregorianCalendar;
unsigned lastItemWeek;
struct weekinfo {
unsigned frequency;
unsigned month;
int year;
} weeklyStats[53];
当一个新值出现时,您只需这样做
- (id)init
{
if ((self = [super init])) {
...
/* Must fix the calendar we're using, or at least understand the one we're
using. Using [NSCalendar currentCalendar] is potentially risky as we
don't necessarily know what that is. */
gregorianCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
...
}
}
- (void)gotNewItemWithDate:(NSDate *)date
{
NSDateComponents *itemComps = [gregorianCalendar
components:(NSWeekOfYearCalendarUnit
| NSCalendarUnitMonth | NSCalendarUnitYear)
fromDate:date];
unsigned week = [itemComps week] - 1; // This runs from 0 to 52 inclusive
unsigned month = [itemComps month];
int year = [itemComps year];
if (week == lastItemWeek)
++weeklyStats[week].frequency;
else {
// Some years don't have week 53 (which we store in weeklyStats[52])
if (week == 0 && lastItemWeek == 51)
weeklyStats[52] = (struct weekinfo){ 0, 0, 0 };
weeklyStats[week] = (struct weekinfo){ 1, month, year };
}
lastItemWeek = week;
}
如果您真的愿意,您可以将其存储在Stat
对象中,但这似乎有点不必要
很明显,您可以扩展此方法来维护每日统计信息等
两个警告:
weeklyStats[52]
可能有效,也可能无效。如果我们最后一次在第52周的话,我选择在第0周的时候清理它weeklyStats[lastItemWeek]
给出的元素不是最终值“我的库”中包含一些关于NSCalendar和NSDate的类别,您可能会发现这些类别很有用。您正在以周为单位硬编码年份长度,这对于某些日历系统来说将是一个突破。@Moshe Yes。这就是为什么代码也硬编码日历,这就是为什么在上面的代码中有一个很大的注释。当然,这只是一个问题,如果OP希望使用用户的本地化日历,而不是公历(在我看来是可疑的),你会对此感到非常惊讶。苹果鼓励本地化。@Moshe我很清楚本地化是被鼓励的,非常感谢(我从2000年开始为苹果系统编写代码)。然而,如果我对OP的意图是正确的,他只想每周提供一份统计数据。实际上,一年中有多少周可以做到这一点并不重要;重要的是在输出端有一个连续的数据流。明确使用公历来获取周数是实现这一点的一种方便方法。