如何按月将日期数组快速分组? [英] How to group array of dates by months in swift?
问题描述
我正在开发一个调度应用程序.我想要给定月份中的所有日期,但是我无法按月份对日期进行分组,但是我想要一个不同的预期结果
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屋!