Нарезка массива в зависимости от даты

У меня есть массив объектов с 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)!
    }
}
Другие вопросы по тегам