如何按月将日期数组快速分组? [英] How to group array of dates by months in swift?

查看:85
本文介绍了如何按月将日期数组快速分组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个调度应用程序.我想要给定月份中的所有日期,但是我无法按月份对日期进行分组,但是我想要一个不同的预期结果

I am working on a scheduling app. I want all the dates of the given months I am not able to group dates by months that is what I tried but I want a different expected result

extension Date {
    static func dates(from fromDate: Date, to toDate: Date) -> [Date] {
        var dates: [Date] = []
        var date = fromDate

        while date <= toDate {
            dates.append(date)
            guard let newDate = Calendar.current.date(byAdding: .day, value: 1, to: date) else { break }
            date = newDate
        }
        return dates
    }
    var month: Int {
        return Calendar.current.component(.month, from: self)
    }
}

let fromDate = Calendar.current.date(byAdding: .day, value: 30, to: Date())
let datesBetweenArray = Date.dates(from: Date(), to: fromDate!)
var sortedDatesByMonth: [[Date]] = []
let filterDatesByMonth = { month in datesBetweenArray.filter { $0.month == month } }
(1...12).forEach { sortedDatesByMonth.append(filterDatesByMonth($0)) }

结果的格式为[[],[],[],[],[],[],[2019-07-31 03:51:19 +0000],…….,[],[],[],[]]

The result is in this format [[], [], [], [], [], [], [2019-07-31 03:51:19 +0000],……., [], [], [], []]

这是我希望得到的结果

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

    init(month: String, dates: [Date]) {
        self.month = month
        self.dates = dates
    }
}
var sections = [ScheduleDates]()

推荐答案

这是一个操场的代码

我认为您的结构可能应该是月份的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)

这篇关于如何按月将日期数组快速分组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆