且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何按月将日期数组快速分组?

更新时间:2022-05-04 22:29:53

这是一个操场的代码

我认为您的结构可能应该是月份的Int值,因为当您填充诸如表视图之类的内容时,如果您将月份设为Strings,则重新排列月份将是PITA

I think your structs should probably be Int values for the months, as when you go to populate something like a tableview, it'll be a PITA to re-order months if you've got them as Strings.

struct ScheduleDates {
    var month: String
    var dates: [Date]
}

无论如何,这是我根据您提供的内容编写的扩展名.坦白地说,您应该返回一个以Int作为键,并以Dates数组作为值的字典,但这就是您想要的...

Anyway, here's the extension I wrote based on what you provided. I frankly think you should return a dictionary with an Int as the key and an array of Dates as the value, but here's what you wanted...

我使用 Dictionary(grouping:by:) 从日期数组中构建字典.

I used Dictionary(grouping:by:) to construct a dictionary from an array of dates.

extension Date {
    static func dateDictionary(from arrayOfDates: [Date]) -> [String: [Date]] {
        // declare a dictionary
        return Dictionary(grouping: arrayOfDates) { date -> String in
            // get the month as an int
            let monthAsInt = Calendar.current.dateComponents([.month], from: date).month
            // convert the int to a string...i think you probably want to return an int value and do the month conversion in your tableview or collection view
            let monthName = DateFormatter().monthSymbols[(monthAsInt ?? 0) - 1]
            // return the month string
            return monthName
        }
    }
}

这是我编写的一种实用程序方法,可以在我弄清楚如何做的同时生成数据.如果您要投入生产,请不要像我在这里那样强行打开包装物.

Here's a utility method I wrote to generate data while I figured out how to do it. If you're going to be in production, don't force unwrap stuff as I did here.

// Utility method to generate dates
func createDate(month: Int, day: Int, year: Int) -> Date? {
    var components = DateComponents()
    components.month = month
    components.day = day
    components.year = year

    return Calendar.current.date(from: components)!
}

下面是我如何生成一组样本日期进行实验.

Below is how I generated an array of sample dates to experiment.

// generate array of sample dates
let dateArray: [Date] = {
    let months = Array(1...12)
    let days = Array(1...31)
    let years = [2019]

    var dateArray: [Date] = []

    while dateArray.count < 100 {
        let randomMonth = months.randomElement()
        let randomDay = days.randomElement()
        let randomYear = years.randomElement()

        if let month = randomMonth,
            let day = randomDay,
            let year = randomYear,
            let date = createDate(month: month,
                                  day: day,
                                  year: year) {
            dateArray.append(date)
        }
    }

    return dateArray
}()

let monthDictionary = Date.dateDictionary(from: dateArray)

var arrayOfStructs: [ScheduleDates] = []

monthDictionary.keys.forEach { key in
    let scheduleDate = ScheduleDates(month: key,
                                     dates: monthDictionary[key] ?? [])
    arrayOfStruct.append(scheduleDate)
}

print(arrayOfStructs)