对比周次
本课属于 Coddy Swift 学习旅程的“逻辑与流程”单元。第 37 课,共 56 课。
最后一个功能:获取两周的数据,并报告每种习惯的变化。
每周数据各自是一份列表,每行包含一个 habit:day 操作。像之前一样构建两个字典,然后比较它们。
我们关注的习惯集合是两周所有键的并集(某个习惯可能只出现在其中一周)。按字母顺序对并集排序后进行遍历。
let allKeys = Set(weekA.keys).union(weekB.keys).sorted()
for name in allKeys {
let a = weekA[name]?.count ?? 0
let b = weekB[name]?.count ?? 0
print("\(name): \(a) -> \(b)")
}?? 0用于处理键缺失的情况。weekA[name]?.count是使用可选链读取计数的方式,无需先解包;如果键不存在,它会返回 nil,而 ?? 0会将其转换为 0。
挑战
中等读取两行输入,每行都是以逗号分隔的 habit:day 条目列表,每周一行。对于任一周中出现的每个习惯,按以下格式打印一行:
<habit>: <a> -> <b> <arrow>其中,a 是第 1 周不同日期的数量,b 是第 2 周不同日期的数量,arrow 为:
- 当
b > a时为UP - 当
b < a时为DOWN - 当
b == a时为SAME
按字母顺序打印习惯。打印完每个习惯对应的行后,再打印一行汇总信息:
Improved: <n>其中,n 是 UP 的习惯数量。
第 1 行输入为 read:1,read:3,workout:2,第 2 行输入为 read:1,read:2,read:5,yoga:7 时,输出为:
read: 2 -> 3 UP
workout: 1 -> 0 DOWN
yoga: 0 -> 1 UP
Improved: 2亲手试试
func parse(_ line: String) -> [String: [Int]] {
var habits: [String: [Int]] = [:]
if line.isEmpty { return habits }
for op in line.components(separatedBy: ",") {
let parts = op.components(separatedBy: ":")
let day = Int(parts[1])!
if !(habits[parts[0], default: []].contains(day)) {
habits[parts[0], default: []].append(day)
}
}
return habits
}
let weekA = parse(readLine()!)
let weekB = parse(readLine()!)
// TODO:取键的并集;每个习惯按 '<name>: a -> b ARROW' 输出;然后输出 'Improved: <n>'
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Swift 在线编辑器