Menu
CoddyTech

标记为已读

本课属于 Coddy Ruby 学习旅程的“逻辑与流程”单元。第 32 课,共 56 课。

添加最后一个选项 4. Mark As Read。用户输入一个完全匹配的书名,程序会将那本书的 :read 键从 false 改为 true。

要查找这本书,请使用 find:它会返回与代码块匹配的第一个元素,如果没有匹配项,则返回 nil:

book = library.find { |b| b[:title] == query }

如果 book 是 nil,就报告没有找到书。否则,直接修改它。Ruby 哈希在数组中共享同一身份,因此更新 book[:read] 也会更新存储在 library 中的条目。

challenge icon

挑战

简单

为菜单循环添加 "4" 分支:

  1. 使用 print 显示提示 Title: ,并读取输入
  2. 使用 find 查找标题完全匹配的书籍
  3. 如果没有匹配项,则显示 Not found.
  4. 否则,将 book[:read] = true 设为真,并显示 Marked as read!

确保之前的所有分支都能正常工作。

对于添加 The Hobbit、将其标记为已读,然后退出的输入,标记代码块会输出:

Choose an option: Title: Marked as read!

亲手试试

library = []

loop do
  puts "--- Library Manager ---"
  puts "1. Add Book"
  puts "2. Search By Title"
  puts "3. Filter By Genre"
  puts "4. Mark As Read"
  puts "5. Exit"
  print "Choose an option: "
  choice = gets.chomp
  if choice == "5"
    puts "Goodbye!"
    break
  elsif choice == "1"
    print "Title: "
    title = gets.chomp
    print "Author: "
    author = gets.chomp
    print "Genre: "
    genre = gets.chomp
    library.push({ title: title, author: author, genre: genre, read: false })
    puts "Book added!"
  elsif choice == "2"
    print "Search title: "
    query = gets.chomp
    matches = library.select { |b| b[:title].downcase.include?(query.downcase) }
    if matches.empty?
      puts "No matches."
    else
      matches.each { |b| puts "#{b[:title]} by #{b[:author]}" }
    end
  elsif choice == "3"
    print "Genre: "
    genre = gets.chomp
    matches = library.select { |b| b[:genre] == genre }
    matches.each { |b| puts "#{b[:title]} by #{b[:author]}" }
    puts "Total: #{matches.length}"
  end
  # TODO:处理 choice == "4",按准确书名查找,
  # 将 book[:read] 设为 true,输出 "Marked as read!" 或 "Not found."
end
quiz icon自我测试

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

逻辑与流程中的所有课

自己练习: Ruby 在线编译器