Объединение и преобразование
Часть раздела Логика и управление потоком путешествия по Ruby на Coddy. Урок 36 из 56.
Две операции встречаются при работе с хешами настолько часто, что в Ruby для них предусмотрены собственные методы.
merge объединяет два хеша в один новый. Если в обоих хешах есть одинаковый ключ, приоритет отдается значению из правого хеша:
defaults = { color: "red", size: "M" }
custom = { size: "L" }
settings = defaults.merge(custom)
puts settings.inspect # {color: "red", size: "L"}Ни один из оригиналов не изменяется, merge возвращает новый хеш.
transform_values создает новый хеш с теми же ключами, но каждое значение пропускается через блок:
prices = { apple: 1, bread: 3 }
with_tax = prices.transform_values { |p| p * 1.2 }
puts with_tax.inspect # {apple: 1.2, bread: 3.6}А transform_keys делает то же самое для ключей, что полезно при преобразовании строк в символы или нормализации регистра:
{ "a" => 1, "B" => 2 }.transform_keys(&:upcase)
# {"A"=>1, "B"=>2}Задание
СреднеДаны два хеша корзин: monday и tuesday, каждый из которых сопоставляет название товара (строку) с его количеством (целым числом). Магазину нужен нормализованный итог за два дня.
Создайте один итоговый хеш, выполнив следующие действия:
- Используйте
mergeдля объединения двух хешей с блоком, чтобы для ключей, присутствующих в обоих хешах, их количества суммировались (а не перезаписывались) - Примените
transform_keys(&:to_sym)к результату, чтобы ключи стали символами - Используйте
transform_valuesдля применения оптовой скидки 10%: каждое количество становится равным(qty * 9 / 10), используя целочисленную арифметику
Выведите итоговый хеш с помощью inspect.
Для данных по умолчанию вывод будет следующим:
{:apples=>9, :bread=>4, :milk=>5, :cheese=>1}(Apples: 5 + 5 = 10, затем 9. Bread: 3 + 2 = 5, затем 4. Milk: 6 только в Monday → 5. Cheese: 2 только в Tuesday → 1.)
Попробуйте сами
monday = { "apples" => 5, "bread" => 3, "milk" => 6 }
tuesday = { "apples" => 5, "bread" => 2, "cheese" => 2 }
# TODO: использовать merge с блоком для суммирования перекрывающихся ключей, затем преобразовать ключи в символы,
# затем применить * 9 / 10 к каждому значению, затем выполнить inspect
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки: подробный разбор
Обзор методов строкИнтерполяция строкПеребор строкРазделение и объединениеПовторение — String Weaver4Блоки, Proc и Lambda
Что такое блок?do..end и фигурные скобкиКлючевое слово yieldПараметры блокаProc и LambdaПовторение — пользовательский итератор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Повторение — конвейер данных3Двумерные массивы
Основы двумерных массивовДоступ к элементам двумерного массиваПеребор двумерных массивовРаспространённые шаблоны для двумерных массивовПовторение — операции с матрицами6Проект — Менеджер библиотеки
Обзор проектаДобавление книгиПотренируйтесь самостоятельно: Онлайн-компилятор Ruby