我目前正在开发一个项目,该项目需要我操作一个带有日期和 double 值的对象数组。我能够将其分解为年份字典,然后将这些嵌套数组分解为当年的几周。不幸的是,一年中的第一周经常出现在其中一年和随后的年份中。
我想要实现的是一个数组或字典,其中包含按周分组的所有日期以及该组中所有金额的总和。
我已经尝试过按 .weekOfYear
对它们进行分组,但是这并没有考虑年份本身,如果两个日期相隔一年以上,我总是只会有一个 52 个条目长的数组。
我还通过使用 Calendar.current.ordinality(of: .weekOfYear, in: .era, for: 'date') 来研究使用一周的序数
但它被转换为整数,我不知道如何将其返回到日期
下面是我在 xCode Playground 中使用的代码的副本及其输出
import Foundation
let cal = Calendar.current
extension Date {
var year: Int {
return cal.component(.year, from: self)
}
var week: Int {
return cal.component(.weekOfYear, from: self)
}
var weekAndYear: DateComponents {
return cal.dateComponents([.weekOfYear, .year], from: self)
}
}
struct Item {
var date: Date
var amount: Double
}
let startDate: Date = cal.date(from: DateComponents(year: 2018, month: 12, day: 2))!
let endDate: Date = cal.date(from: DateComponents(year: 2019, month: 1, day: 28))!
// Here I'm creating dummy items for each date between our date range
func setUpItems (startDate: Date, endDate: Date) -> [Item] {
var date = startDate
var inputArray: [Item] = []
let dateCount = cal.dateComponents([.day], from: startDate, to: endDate).day
let valuePerDay: Double = 1000 / Double(dateCount!)
let lowerLim = valuePerDay - (valuePerDay / 2)
let upperLim = valuePerDay + (valuePerDay / 2)
while date < endDate {
let input = Double.random(in: lowerLim...upperLim).rounded()
inputArray.append(Item(
date: date,
amount: input
))
date = cal.date(byAdding: .day, value: 1, to: date)!
}
return inputArray
}
let itemArray = setUpItems(startDate: startDate, endDate: endDate)
let grouppedByYear = Dictionary(grouping: itemArray, by: { $0.date.year })
let grouppedByYearThenWeek = grouppedByYear
.mapValues{(yearArray: [Item]) -> Dictionary<Int, Double> in
return Dictionary(grouping: yearArray, by: { $0.date.week })
.mapValues{ (value: [Item]) in
return value.map{ $0.amount }.reduce(0, +)
}
}
print("Grouped by week")
print(grouppedByYearThenWeek)
由此您可以预期输出如下所示
Grouped by week
[2018: [49: 127.0, 52: 125.0, 50: 119.0, 51: 113.0, 1: 39.0],
2019: [3: 124.0, 4: 122.0, 5: 19.0, 1: 87.0, 2: 121.0]]
我希望最终得到一本不会根据年份分割一周的字典
[2018: [49: 127.0, 52: 125.0, 50: 119.0, 51: 113.0],
2019: [3: 124.0, 4: 122.0, 5: 19.0, 1: 126.0, 2: 121.0]]
// or potentially
[["49 2018": 127.0, "52 2018": 125.0...],
["3 2019": 124.0, "4 2019": 122.0...]]
任何帮助将不胜感激。
最佳答案
Unfortunately the first week of the year is often present in one of the years and the following.
是的。但如果您要检索一年中的第几周,则使用 .year
检索它是没有意义的。您希望将 .yearForWeekOfYear
与 .weekOfYear
结合使用:
var weekAndYear: DateComponents {
return cal.dateComponents([.weekOfYear, .yearForWeekOfYear], from: self)
}
var yearForWeekOfYear: Int {
return cal.component(.yearForWeekOfYear, from: self)
}
您可能会发现“一周开始”计算属性很有用:
var startOfWeek: Date {
let components = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
return cal.date(from: components)!
}
这取决于您想要如何对待 2018 年 12 月 31 日。您希望它出现在 2019 年的第一周吗(就像标准的 weekOfYear
和 yearForWeekOfYear
code> 确实),或者您想将其归因于“2018 年第 53 周”。简而言之,您是否要将 2018 年 12 月 30 日开始的一周视为一周(上面将实现),还是要将其分开,将一周的开始视为 2018 年第 53 周及其后一部分2019 年第 1 周是哪一周?
关于arrays - Swift - 在一个大的时间范围内按一年中的一周对一系列项目进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54464912/