根据日期条件切片数组

时间:2017-11-05 18:56:54

标签: arrays swift algorithm date slice

我有一个具有Date属性的对象数组。数组按降序排序,即索引0处的元素是最新的,最后一个元素是最旧的元素。例如:Array[0] = 2017-11-05Array[1] = 2017-11-04

从这个数组中,我想创建一个包含Arrays的数组,该数组基于月份的截止日期。例如,如果截止日期是每个月的第6天:

Array = [2017-11-07, 
         2017-11-06, 
         2017-11-05, 
         2017-11-04]

应该产生

NewArray = [[2017-11-07, 
             2017-11-06], 
            [2017-11-05, 
             2017-11-04]]

我已根据我能想到的所有不同场景编写了我的算法(我不会在这里发布它,因为它的长而且充满了if and else语句)。例如,如果列表中的两个相邻元素在同一个月,我检查第一个元素日是> =关闭日,第二个元素日是<截止日期。然后有些情况下,其中一个元素提前一个月,或者提前几个月。哦,还有两者之间存在年份差异的情况,这会搞砸其他条件。

我完全陷入困境,因为我正在使用边缘案例测试我的算法。随着我继续前进,我提出了越来越多的边缘案例,if and else语句的数量似乎走向无限。是否有不同的方法,因为我无法弄清楚如何在没有大量if and else条件的情况下编写算法。

修改 更有问题的案例。

Array = [2018-01-06, 
         2017-12-07, 
         2017-12-05, 
         2017-12-04,
         2017-11-16,
         2017-11-05,
         2017-09-27,
         2017-02-08,
         2016-12-07]

如果截止日期是第6个所需的输出:

NewArray = [[2018-01-06], 
            [2017-12-07], 
            [2017-12-05, 
             2017-12-04,
             2017-11-16],
            [2017-11-05],
            [2017-09-27],
            [2017-02-08],
            [2016-12-07]]

例如,这种情况要求算法开始一个新的列表,其中月份差异是> = 2.在月份差异是1,即相隔一个月的情况下,它必须检查其中一个元素day是> =结束日期(和)其他元素日是<截止日期。在元素在同一个月的情况下,需要检查元素之一是否是> =关闭日期和其他元素日<截止日期。当列表中有不同年份的元素时,仅仅这些条件不会很好。

1 个答案:

答案 0 :(得分:0)

如果我正确理解您的问题,请使用Calendar方法

正是您要找的。它允许您计算第6天 在给定日期之前发生的一个月。然后比较每个 在下一个当前结束日期的日期,并附加 它到当前切片,或者开始一个新切片并计算下一个切片 (即上次提前)截止日期:

let yourDates: [Date] = ... // Your array of dates (in descending order)

let matchComponents = DateComponents(day: 6)
let cal = Calendar.current

var nextClosingDate = Date.distantFuture // So that the first date will start a new slice
var slicedDates: [[Date]] = []

for date in yourDates {
    if date >= nextClosingDate {
        // Append to current slice:
        slicedDates[slicedDates.count - 1].append(date)
    } else {
        // Start new slice and compute next closing date:
        slicedDates.append([date])
        nextClosingDate = cal.nextDate(after: date,
                                       matching: matchComponents,
                                       matchingPolicy: .nextTime,
                                       direction: .backward)!
    }
}