Menu
CoddyTech

对比周次

本课属于 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。

challenge icon

挑战

中等

读取两行输入,每行都是以逗号分隔的 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>'
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: Swift 在线编辑器