我有一个具有Date
属性的对象数组。数组按降序排序,即索引0处的元素是最新的,最后一个元素是最旧的元素。例如:Array[0] = 2017-11-05
,Array[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是> =结束日期(和)其他元素日是<截止日期。在元素在同一个月的情况下,需要检查元素之一是否是> =关闭日期和其他元素日<截止日期。当列表中有不同年份的元素时,仅仅这些条件不会很好。
答案 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)!
}
}