The function calculates the sum of duration values for each title. This works as written but I feel it could be improved upon with either calculating the sum of durations during the fetch or better use of .map and .reduce and somehow removing the for-loop.
The entity "record" has attributes "endDate", "duration" and "title" were titles map one to many.
Any insights would be appreciated.
Here is a sample data set for "record" entity:
- [duration: 35.5, endDate: date(), title :"reading"],
- [duration: 25.0, endDate: date(), title :"reading"],
- [duration: 20, endDate: date(), title :"memrise"],
- [duration: 70, endDate: date(), title :"memrise"],
- [duration: 50, endDate: (other date), title :"memrise"]
for these, the predicate filters out the 5th entry and the function returns
(["reading","memrise"],[60.5, 90])
func getAllTitlesDurations(date: Date) -> (titles: [String], duration: [Double]) {
// date extension to get first and last moment of date
let dateDayStart = date.startOfDay
let dateDayNext = date.endOfDay
var durations : [Double] = []
var titles : [String] = []
// core data fetch, predicate to today
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return ([],[])
}
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entityNames.Record.rawValue)
fetchRequest.predicate = NSPredicate(format:"(endDate >= %@) AND (endDate < %@)", dateDayStart as CVarArg, dateDayNext as CVarArg)
do {
let records = try context.fetch(fetchRequest) as! [Record]
// create unique titles
titles = Array(Set(records.map{$0.title!}))
for m in titles {
durations.append(records
.filter{$0.title == m}
.reduce(0){$0 + $1.duration})
}
//MARK : Check outputs
print (durations)
print(titles)
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
return ([],[])
}
return (titles, durations)
}