既読にする
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 に格納されているエントリも更新されます。
チャレンジ
簡単メニューのループを "4" の分岐で拡張します:
printでプロンプトTitle:を表示し、入力を読み取りますfindを使用して、その正確なタイトルを持つ本を特定します- 一致するものがない場合は、
Not found.と出力します - それ以外の場合は、
book[:read] = trueを設定し、Marked as read!と出力します
以前のすべての分岐が動作し続けるようにしてください。
The Hobbit を追加し、それを既読としてマークしてから終了する入力の場合、マークするブロックは次のように出力します:
Choose an option: Title: Marked as read!チートシート
find を使用して、配列内で最初に一致する要素を特定します(見つからない場合は nil を返します):
book = library.find { |b| b[:title] == query }ハッシュは配列内で同一性を共有するため、見つかったオブジェクトを変更すると元のエントリも更新されます:
if book.nil?
puts "Not found."
else
book[:read] = true
puts "Marked as read!"
end自分で試してみよう
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
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。