I have an Array of Dictionaries.
The Dictionary is like ["date":"2017-07-03T10:12:00", "amount":2.1]
.
EDIT
Let's say, I have the following array.
let dic1 = ["date":"2017-07-03T10:12:00", "amount":2.0]
let dic2 = ["date":"2017-07-03T11:15:03", "amount":4.0]
let dic3 = ["date":"2017-07-03T17:05:04", "amount":1.0]
let dic4 = ["date":"2017-07-04T09:05:03", "amount":3.0]
let dic5 = ["date":"2017-07-04T12:01:22", "amount":5.0]
let dic6 = ["date":"2017-07-04T19:01:01", "amount":2.0]
let array = [dic1, dic2, dic3, dic4, dic5, dic6]
Now I'm trying to calculate the following result from Array.
"date":"2017-07-03", "average":3.5
"date":"2017-07-04", "average":5.0
"date":"2017-07", "average":2.82..
"date":"2017", "average":2.82..
I could get the average of all data with the following code but I'm stuck now.
let average = array.flatMap({ $0["amount"] as? Double }).reduce(0, +) / Double(array.count)
Suggestion using a custom struct including a date formatter to convert the ISO8601 string to Date
struct Item {
let date : Date
let amount : Double
static let dateFormatter : ISO8601DateFormatter = {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withFullDate, .withTime, .withColonSeparatorInTime]
return formatter
}()
init(date: String, amount: Double) {
self.date = Item.dateFormatter.date(from: date)!
self.amount = amount
}
}
Populate the array
let items = [Item(date : "2017-07-03T10:12:00", amount :2.0),
Item(date : "2017-07-03T11:15:03", amount :4.0),
Item(date : "2017-07-03T17:05:04", amount :1.0),
Item(date : "2017-07-04T09:05:03", amount :3.0),
Item(date : "2017-07-04T12:01:22", amount :5.0),
Item(date : "2017-07-04T19:01:01", amount :2.0)]
Create a function to take the array and specific date components as parameters
func average(of items: [Item], matching components: DateComponents) -> Double
{
let filteredDates = items.filter { Calendar.current.date($0.date, matchesComponents: components) }
return filteredDates.map{ $0.amount }.reduce(0.0, +) / Double(filteredDates.count)
}
Now filter the items by date components and return the average value
average(of: items, matching: DateComponents(year: 2017, month: 7, day: 3))
average(of: items, matching: DateComponents(year: 2017, month: 7, day: 4))
average(of: items, matching: DateComponents(year: 2017, month: 7))
average(of: items, matching: DateComponents(year: 2017))