Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 按小时、天、周、月、年对数据进行聚类目标c_Objective C_Nsdate_Nsdatecomponents - Fatal编程技术网

Objective c 按小时、天、周、月、年对数据进行聚类目标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

我有一个属性为time和count的Stat对象。我有一个(按时间排序)每小时都会出现的这些对象的列表。我想聚集起来展示一下。 在objective c中是否有一种按时间对数据进行聚类的好方法?还是一个比下面的幼稚算法更好的算法

这是一个每周做一次的例子。其他的都是类似的,但是您可以更改日期组件

-(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
对象中,但这似乎有点不必要

很明显,您可以扩展此方法来维护每日统计信息等

两个警告:

  • 几周是棘手的;有些年份有53周,有些年份有52周。因此,
    weeklyStats[52]
    可能有效,也可能无效。如果我们最后一次在第52周的话,我选择在第0周的时候清理它

  • weeklyStats[lastItemWeek]
    给出的元素不是最终值


  • “我的库”中包含一些关于NSCalendar和NSDate的类别,您可能会发现这些类别很有用。您正在以周为单位硬编码年份长度,这对于某些日历系统来说将是一个突破。@Moshe Yes。这就是为什么代码也硬编码日历,这就是为什么在上面的代码中有一个很大的注释。当然,这只是一个问题,如果OP希望使用用户的本地化日历,而不是公历(在我看来是可疑的),你会对此感到非常惊讶。苹果鼓励本地化。@Moshe我很清楚本地化是被鼓励的,非常感谢(我从2000年开始为苹果系统编写代码)。然而,如果我对OP的意图是正确的,他只想每周提供一份统计数据。实际上,一年中有多少周可以做到这一点并不重要;重要的是在输出端有一个连续的数据流。明确使用公历来获取周数是实现这一点的一种方便方法。