В настоящее время я работаю над проектом, который требует от меня манипулирования массивом объектов, которые принимают дату и двойное значение.Я могу разбить его в словаре лет, а затем эти вложенные массивы по неделям того года.К сожалению, первая неделя года часто присутствует в одном из следующих лет.
Я хочу достичь массива или словаря всех дат, сгруппированных по каждой отдельной неделе, и суммы всех сумм.в этой группе.
Я уже пытался сгруппировать их по .weekOfYear
, однако это не учитывает сам год, и если бы эти две даты были на расстоянии более года, я бы всегдаесть только массив длиной 52 записи.
Я также изучил использование порядкового номера недели с помощью Calendar.current.ordinality(of: .weekOfYear, in: .era, for: 'date')
, но он преобразуется в целое число, и я не уверен, как потом вернуть его обратнона дату
Ниже приведена копия моего кода, который я использую на игровой площадке xCode, и его вывод
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...]]
Любая помощь будет принята с благодарностью.