【问题标题】:Finding smallest time interval (between now and date from array)查找最小时间间隔(从现在到数组中的日期)
【发布时间】:2014-01-23 04:10:13
【问题描述】:

目前正在寻找最佳解决方案,以找到当前时间和我的数组中的日期之间的最小时间间隔。

我有一个接受 NSArray 并返回 NSArray 的方法。该方法执行以下操作:

  1. 循环遍历按时间排序的数组(0 索引最接近当前时间)
  2. 通过查找增量和比较来查找最小区间
  3. 获取该索引,获取它,返回一个字典

我开始考虑使用timeIntervalSinceDate 等代替我在下面使用的手动工作。

数组看起来像这样:

tideSummary: [{

'type' : 'High Tide',
'pretty' : 'January 16 at 5:13PM EST',
'epoch' : '325267782',

...

}]

这段代码是否因为它试图做的事情而显得臃肿?我觉得根据索引和键值提取某些数据存在大量重复?

我想从数组中返回最近的时间,所以我想使用timeIntervalSince1970 并做一些简单的数学运算来找到最小的增量。我的数组包含一个以毫秒为单位返回时间的键


关于如何清理条件以便我仍然可以提取的任何建议:lowTideTime - highTideTimetideType

以下是我用来提取此信息的方法:

- (NSArray *)findUpcomingTides: (NSArray *)arrayOfTideCycles {
    NSTimeInterval currentDateInterval;
    currentDateInterval = [[NSDate date]timeIntervalSince1970];
    NSInteger smallestDelta = currentDateInterval;
    NSArray *upcomingTideData = [[NSArray alloc] init];

    for (NSInteger i = 0; i < arrayOfTideCycles.count; i++) {

        NSDictionary *eachTideSummary = [arrayOfTideCycles objectAtIndex:i];
        NSInteger tideDateAsEPOCH = [[eachTideSummary valueForKeyPath:@"epoch"] intValue];
        NSInteger dateDelta = tideDateAsEPOCH - smallestDelta;
        if (dateDelta < smallestDelta) {
            smallestDelta = dateDelta;

            int iPlusOne = i+1;

            upcomingTide = [arrayOfTideCycles objectAtIndex:i];
            NSDictionary *tideTypeDictionary = [arrayOfTideCycles objectAtIndex:i];
            tideType = [tideTypeDictionary objectForKey:@"type"];

            if([[upcomingTide valueForKeyPath:@"type"] isEqualToString:@"Low Tide"] || [[upcomingTide valueForKeyPath:@"type"] isEqualToString:@"Max Ebb"]){

                NSString *lowTidePrettyDateFormat = [upcomingTide valueForKeyPath:@"pretty"];
                lowTideTime = [self convertAndFormatDateToTimeWithString:lowTidePrettyDateFormat];


                NSDictionary *upcomingHighTide = [arrayOfTideCycles objectAtIndex:iPlusOne];
                NSString *highTidePrettyDateFormat = [upcomingHighTide valueForKeyPath:@"pretty"];
                highTideTime = [self convertAndFormatDateToTimeWithString:highTidePrettyDateFormat];

            } else {

                NSString *highTidePrettyDateFormat = [upcomingTide valueForKeyPath:@"pretty"];
                highTideTime = [self convertAndFormatDateToTimeWithString:highTidePrettyDateFormat];

                NSDictionary *upcomingLowTide = [arrayOfTideCycles objectAtIndex:iPlusOne];
                NSString *lowTidePrettyDateFormat = [upcomingLowTide valueForKeyPath:@"pretty"];
                lowTideTime = [self convertAndFormatDateToTimeWithString:lowTidePrettyDateFormat];
            }

            upcomingTideData = [NSArray arrayWithObjects:lowTideTime, highTideTime, tideType, nil];
        }
    }

    return upcomingTideData;
}

关于如何清理这个有什么建议吗?

【问题讨论】:

  • 如果您的数组已排序,请使用二进制搜索。

标签: ios objective-c arrays


【解决方案1】:

据我了解,您不喜欢在这种并行性中违反 DRY 的问题:

NSString *lowTidePrettyDateFormat = [upcomingTide valueForKeyPath:@"pretty"];
lowTideTime = [self convertAndFormatDateToTimeWithString:lowTidePrettyDateFormat];
NSDictionary *upcomingHighTide = [arrayOfTideCycles objectAtIndex:iPlusOne];
NSString *highTidePrettyDateFormat = [upcomingHighTide valueForKeyPath:@"pretty"];
highTideTime = [self convertAndFormatDateToTimeWithString:highTidePrettyDateFormat];

NSString *highTidePrettyDateFormat = [upcomingTide valueForKeyPath:@"pretty"];
highTideTime = [self convertAndFormatDateToTimeWithString:highTidePrettyDateFormat];
NSDictionary *upcomingLowTide = [arrayOfTideCycles objectAtIndex:iPlusOne];
NSString *lowTidePrettyDateFormat = [upcomingLowTide valueForKeyPath:@"pretty"];
lowTideTime = [self convertAndFormatDateToTimeWithString:lowTidePrettyDateFormat];

据我乍一看,它们是完全一样的(除了一些不重要的局部变量名)。因此,将它们分解成一个方法,该方法采用 upcomingTide 值并返回两个潮汐时间的数组(或者这两个代码应该为您生成的任何内容)。

【讨论】:

  • 好的,谢谢@matt。是的,基本上如果type == Low Tide -> 存储这个,否则使用另一个。
【解决方案2】:

一些建议:

valueForKeyPath 是一个非常通用且复杂的方法,运行速度会比较慢; objectForKey 会快很多。

如果您的数组包含以毫秒为单位的数据,那么您的代码就有问题。 intValue 仅处理大约 +/- 20 亿之间的值。 20 亿毫秒 = 200 万秒 = 一个月多一点。使用 longLongValue 或 doubleValue。 (如果您的数据实际上以秒为单位,那么您的代码将在 2038 年左右的某个时间出错)。

我不知道你到底想做什么,但是这个

    NSInteger dateDelta = tideDateAsEPOCH - smallestDelta;
    if (dateDelta < smallestDelta) {
        smallestDelta = dateDelta;

错了。只需使用调试器逐步完成它,看看值如何变化。我敢肯定你会想要一个绝对值在那里的某个地方。

如果最后一个数组元素给出最小的增量,您的代码将崩溃,因为您将访问数组之外​​的另一个数组元素。

如果您有 10,000 个数组元素,在当前日期之前有 5000 个,在当前日期之后有 5000 个,那么您将找到迄今为止最好的元素 5000 次,并且每次都进行重要的工作。我会首先找到最好的数组元素,然后找到你想要的数据。

【讨论】:

  • 我通过比较 MS 中的当前日期/时间和 MS 中的潮汐时间,将其用作捕获最小增量。我从smallestDelta 的高值开始,因此每次传递都会变小。当最小的捕获时,我然后抓住索引。
  • 还用数组数据更新了我的问题,以举例说明是否有帮助。
  • 当你说:I'd first find the best array element, and when that is found, get the data that you want. - 这就是我想做的就是根据当前时间找到下一个潮汐时间。但是您说它在每个索引上都做了重要的工作。
猜你喜欢
  • 2015-04-26
  • 2017-10-27
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多