Нарезка массива в зависимости от даты
У меня есть массив объектов с Date
имущество. Массив сортируется в порядке убывания даты, т.е. элемент с индексом 0 является самым новым, а последний элемент - самым старым. Например: Array[0] = 2017-11-05
, Array[1] = 2017-11-04
Из этого массива я хочу создать массив, содержащий массивы с объектами, основанные на том, какой день месяца является датой закрытия. Например, если дата закрытия 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, т. Е. С интервалом в один месяц, он должен проверить, равен ли один из элементов дня>= дата закрытия (и) дня других элементов - <дата закрытия. В тех случаях, когда элементы находятся в одном и том же месяце, необходимо проверить, является ли один из элементов дня>= датой закрытия, а другие элементы дня <датой закрытия. Только одни эти условия не будут хорошо работать, когда в списке есть элементы с разными годами.
1 ответ
Если я правильно понимаю вашу проблему, Calendar
метод
nextDate(after:matching:matchingPolicy:repeatedTimePolicy:direction:)
это то, что вы ищете. Это позволяет вам вычислить 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)!
}
}