Отметить как прочитанное
Часть раздела Логика и управление потоком путешествия по Ruby на Coddy — урок 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
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Обзор методов строкИнтерполяция строкИтерация по строкамSplit и JoinИтоги — String Weaver4Блоки, Proc и лямбды
Что такое блок?do..end против фигурных скобокКлючевое слово yieldПараметры блокаProc и лямбдыИтоги: пользовательский итератор7Хеши. Часть 2
Hash.new со значениями по умолчаниюИтерация по хешамВложенные хешиСлияние и преобразованиеИтоги — счетчик частоты10Проект — Учёт студентов
Обзор проектаДобавить студента2Диапазоны
Что такое диапазон?Методы диапазоновДиапазоны в Case / WhenПовторение — практика по диапазонам5Мощь Enumerable
Select и RejectЦепочки MapReduce / Injectcount, all?, any?, none?group_by и partitionsort_by, min_by, max_byИтоги — Data Pipeline8Продвинутые условные конструкции
Case с классами и RegexМножественные значения в whenТернарный операторОднострочные if / unlessПовторение: Классификатор оценок3Двумерные массивы
Основы двумерных массивовДоступ к элементам двумерного массиваИтерация по двумерным массивамРаспространенные 2D-паттерныИтоги: Операции с матрицами6Проект — Менеджер библиотеки
Обзор проектаДобавление книги