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

时间:2019-07-31 04:02:29

标签: ios swift

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

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],……。,[],[],[],[]]

这是我希望得到的结果

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

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

3 个答案:

答案 0 :(得分:2)

如果您想按月对日期进行分组,可以创建一个Dictionary,如下所示:

Dictionary(grouping: datesBetweenArray, by: { $0.month })

这将导致以下输出,格式为[Int: [Date]]

字典的键将是您的月份。

现在,您可以通过以下方式遍历此字典来初始化scheduleDates结构:

var sections = Dictionary(grouping: datesBetweenArray,
                          by: ({$0.month}))
    .map { tuple in
        ScheduleDates(month: String(tuple.0), dates: tuple.1)
}

答案 1 :(得分:1)

这是一个操场的代码

我认为您的结构可能应该是几个月的Int值,因为当您填充诸如表格视图之类的东西时,如果您将几个月定为{ {1}}。

Strings

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

我用Dictionary(grouping:by:)从日期数组中构建了一个字典。

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

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

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
        }
    }
}

下面是我如何生成样本日期数组进行实验的方法。

// 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)!
}

答案 2 :(得分:0)

您可以使用我的代码。我写来适应您的情况。

let fromDate = Calendar.current.date(byAdding: .day, value: 30, to: Date())
let datesBetweenArray = Date.dates(from: Date(), to: fromDate!)
if datesBetweenArray.count <= 1 {
    print(datesBetweenArray)
}
var sortedDatesByMonth: [[Date]] = []
var tempMonth = datesBetweenArray[0].month
var dates: [Date] = []
for i in 0..<datesBetweenArray.count {

    if tempMonth == datesBetweenArray[i].month {
        dates.append(datesBetweenArray[i])
        if i == datesBetweenArray.count - 1 {
            sortedDatesByMonth.append(dates)
        }
    } else {
        sortedDatesByMonth.append(dates)
        tempMonth = datesBetweenArray[i].month
        dates.removeAll()
        dates.append(datesBetweenArray[i])
    }
}
print(sortedDatesByMonth.count)
print(sortedDatesByMonth)