Получить массив дат из массива дат - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть массив Date объектов, как в следующем примере:

let dates = [date1, date2, date3, date4, date5]

Как создать подмассивы для дат с одинаковыми day of month, month и year.

Пример:

date1 = 20/04/2020
date2 = 19/04/2020
date3 = 19/04/2020
date4 = 18/04/2020
date5 = 18/04/2020
...

С этим я хотел следующее:

let group1 = [date1]
let group2 = [date2, date3] 
let group3 = [date4, date5]
let group4 = //...

Я пробовал DateComponents и .map, .filter, et c функции, но почему-то я не могу этого сделать.

Могу ли я получить подсказку?

спасибо.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Код извлекает компоненты даты для года, месяца и дня из каждой даты и группирует их, а затем отображает значения из сгруппированного результата в массив массивов на дату. Чтобы иметь возможность иметь исходные даты в конечном результате, кортеж используется в качестве типа значения для словаря

let groupedDates = Dictionary(grouping: dates
    .map { ($0,Calendar.current.dateComponents([.year, .month, .day], from: $0))}, by: {$0.1})
    .mapValues {value in value.map {$0.0}}
    .values
0 голосов
/ 20 апреля 2020

Просто создайте структуру, которая отслеживает год, месяц и день.

struct DateCluster {
    let day: Int
    let month: Int
    let year: Int

    var dates: [Date] = []

    init(date: Date) {
        let cal = Calendar.current
        day = cal.component(.day, from: date)
        month = cal.component(.month, from: date)
        year = cal.component(.year, from: date)

        dates.append(date)
    }

    func doesDateBelong(_ date: Date) -> Bool {
        let cal = Calendar.current
        return cal.component(.day, from: date) == day
            && cal.component(.month, from: date) == month
            && cal.component(.year, from: date) == year
    }
}

А вот использование:

func makeDate(year: Int, month: Int, day: Int) -> Date? {
    let cal = Calendar.current
    let components = DateComponents(year: year, month: month, day: day)
    return cal.date(from: components)
}

var clusters: [DateCluster] = []


var dates = [
    makeDate(year: 2020, month: 4, day: 20),
    makeDate(year: 2020, month: 4, day: 19),
    makeDate(year: 2020, month: 4, day: 19),
    makeDate(year: 2020, month: 4, day: 18),
    makeDate(year: 2020, month: 4, day: 18),
].compactMap { $0 }


for date in dates {
    if let index = clusters.firstIndex(where: { $0.doesDateBelong(date) }) {
        clusters[index].dates.append(date)
    } else {
        clusters.append(.init(date: date))
    }
}

В результате ниже будет массив из массива даты все сгруппированы по году, месяцу и дню.

let groupedDates = clusters.map { $0.dates }
...