If you are grouping these for grouping these in the UI, I would suggest a few things:
AfterData should use Date, not String.
- When you present this in the UI, use a user-friendly date formatter rather than the cryptic
yyyy/MM/dd format. E.g., a dateStyle of .medium.
- I would use
reduce to calculate the totals by day, sort to sort them, and map to create your custom objects.
- FWIW, using this pattern, you are no longer dependent upon the input data having already been sorted.
So, perhaps:
struct BeforeData {
var value: Int
var date: Date
}
struct AfterData {
var sum: Int
var date: Date // note, not `String`
}
let iso = ISO8601DateFormatter()
let date1 = iso.date(from: "2022-01-01T12:00:00Z")!
let date2 = iso.date(from: "2022-01-01T14:11:00Z")!
let date3 = iso.date(from: "2022-01-02T07:00:00Z")!
let date4 = iso.date(from: "2022-01-02T12:00:00Z")!
let date5 = iso.date(from: "2022-01-03T08:00:00Z")!
let before = [
BeforeData(value: 100, date: date1),
BeforeData(value: 150, date: date2),
BeforeData(value: 120, date: date3),
BeforeData(value: 120, date: date4),
BeforeData(value: 200, date: date5)
]
let calendar = Calendar.current
let grouped = before
.reduce(into: [Date: Int]()) { dictionary, object in
let day = calendar.startOfDay(for: object.date)
dictionary[day, default: 0] += object.value
}
.sorted { $0.0 < $1.0 }
.map { AfterData(sum: $0.value, date: $0.key) }
And then:
let formatter = DateFormatter()
formatter.dateStyle = .medium
for value in grouped {
print(formatter.string(from: value.date), value.sum)
}
And a US user will see:
Jan 1, 2022 370
Jan 2, 2022 120
Jan 3, 2022 200
But a UK user will see:
1 Jan 2022 370
2 Jan 2022 120
3 Jan 2022 200
Then we are showing dates in the format with which the end-user is comfortable.