我知道我的标题有些令人困惑,但让我解释一下: 我已经有一段时间了,我似乎无法解决这个问题。
首先,这是我的一些代码:
struct CalorieLog {
var date: Date
var calories: Int
}
var logs: [CalorieLog] = []
func logCalories() {
//... calculate calories to log
let currentDate: Date = Date()
let calories: Int = calculatedCalories
logs.append(CalorieLog(date: currentDate, calories: calculatedCalories))
}
现在如何在白天对日志数组中的CalorieLog项目进行分组,并获得每天记录的所有卡路里的总和?也许可以将它们分成一系列字典?例如字典(字符串:Int)使得(日:总卡路里)
请不要苛刻我仍然是新手开发者。提前谢谢。
答案 0 :(得分:1)
您尝试做的很多事情都可以使用Swift的map
,sorted
,filtered
和reduce
函数来完成。
struct CalorieLog {
var date: Date
var calories: Int
}
var logs: [CalorieLog] = []
// I changed your method to pass in calculatedCalories, we can make that random just for learning purposes. See below
func logCalories(calculatedCalories: Int) {
let currentDate: Date = Date()
logs.append(CalorieLog(date: currentDate, calories: calculatedCalories))
}
// This is a method that will calculate dummy calorie data n times, and append it to your logs array
func addDummyCalorieData(n: Int, maxRandomCalorie: Int) {
for _ in 1...n {
let random = Int(arc4random_uniform(UInt32(maxRandomCalorie)))
logCalories(calculatedCalories: random)
}
}
// Calculate 100 random CalorieLog's with a max calorie value of 1000 calories
addDummyCalorieData(n: 100, maxRandomCalorie: 1000)
// Print the unsorted CalorieLogs
print("Unsorted Calorie Data: \(logs)")
// Sort the logs from low to high based on the individual calories value.
let sortedLowToHigh = logs.sorted { $0.calories < $1.calories }
// Print to console window
print("Sorted Low to High: \(sortedLowToHigh)")
// Sort the CalorieLogs from high to low
let sortedHighToLow = logs.sorted { $1.calories < $0.calories }
// Print to console window
print("Sorted High to Low: \(sortedHighToLow)")
// Sum
// This will reduce the CaloreLog's based on their calorie values, represented as a sum
let sumOfCalories = logs.map { $0.calories }.reduce(0, +)
// Print the sum
print("Sum: \(sumOfCalories)")
如果您想将CalorieLogs映射为一系列词典,您可以这样做:
let arrayOfDictionaries = logs.map { [$0.date : $0.calories] }
然而,这种效率低下。你为什么想要一系列字典?如果您只是想跟踪特定日期消耗/燃烧的卡路里,您可以只创建一个字典,其中日期是您的密钥,而Int
数组是表示该日所有卡路里的值。你可能只需要一本字典,即
var dictionary = [Date : [Int]]()
然后你可以通过说dictionary[Date()]
找到约会的所有卡路里。但请记住,您必须拥有确切的日期和时间。您可能希望将字典中的键更改为String
类似于2/19/2017
之类的日期,这可以更容易地进行比较。在设计模型时必须考虑到这一点。
答案 1 :(得分:1)
很大程度上取决于你所说的“日”。因此,在这个高度简化的示例中,我只使用默认定义,即日历为特定日期定义的日期(不考虑时区现实)。
以下是一些基本数据:
struct CalorieLog {
var date: Date
var calories: Int
}
var logs: [CalorieLog] = []
logs.append(CalorieLog(date:Date(), calories:150))
logs.append(CalorieLog(date:Date(), calories:140))
logs.append(CalorieLog(date:Date()+(60*60*24), calories:130))
现在我们构建一个字典,其中键是日期日的常规,值是包含该日作为日期的所有日志的数组:
var dict = [Int:[CalorieLog]]()
for log in logs {
let d = log.date
let cal = Calendar(identifier: .gregorian)
if let ord = cal.ordinality(of: .day, in: .era, for: d) {
if dict[ord] == nil {
dict[ord] = []
}
dict[ord]!.append(log)
}
}
你的CalorieLogs现在已经成熟了几天!现在可以很容易地浏览该字典并将每个天的日志数组的卡路里相加。我不知道你最终想要对这些信息做些什么,所以我只是打印它,以证明我们的字典组织是有用的:
for (ord,logs) in dict {
print(ord)
print(logs.reduce(0){$0 + $1.calories})
}
答案 2 :(得分:1)
要按日期排序日志,您只需执行以下操作:
logs.sorted(by: { $0.date < $1.date })
要获得一个字典,将一天映射到当天的卡路里总和,您可以这样做:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy"
var calorieCalendar = [String: Int]()
for log in logs {
let date = dateFormatter.string(from: log.date)
if let _ = calorieCalendar[date] {
calorieCalendar[date]! += log.calories
} else {
calorieCalendar[date] = log.calories
}
}
对于像这样的logs
设置
logs.append(CalorieLog(date: Date(), calories: 1))
logs.append(CalorieLog(date: Date.init(timeIntervalSinceNow: -10), calories: 2))
logs.append(CalorieLog(date: Date.init(timeIntervalSinceNow: -60*60*24*2), calories: 3))
上面的代码将生成如下字典:
["17 Feb 2017": 3, "19 Feb 2017": 3]