Как и у массивов, базовый метод обработки хешей это each
(или алиас each_pair
). Он принимает на вход блок, в который передаются и ключ, и значение:
data = {
clojure: 'dynamic',
go: 'static',
kotlin: 'static'
}
data.each do |key, value|
# логика
end
С его помощью можно выполнить любую задачу по преообразованию хеша, но в каждой конкретной ситуации лучше пользоваться специализированными функциями, которые позволяют сократить код и сделать его понятнее.
Этот метод позволяет преобразовать значения, оставив ключи. На выходе получается новый хеш:
new_data = data.transform_values { |value| value.upcase }
# { clojure: "DYNAMIC", go: "STATIC", kotlin: "STATIC" }
С помощью этого метода можно даже поменять тип значений и сделать их, например, массивами. Точно такой же метод есть и для ключей: transform_keys.
Слайс позволяет извлечь из хеша только его часть по указанным ключам:
data.slice(:clojure, :go)
# { clojure: "dynamic", go: "static" }
Для более сложных ситуаций подходит метод select
— он действует как фильтр и извлекает из хеша его часть, которая соответствует нужным условиям:
data.select { |key, value| value == 'static' }
# { go: "static", kotlin: "static" }
Иногда бывает полезно проверить хеш на пустоту, за это отвечает метод empty?
и проверить в хеше наличие ключа - это метод key?
:
data.empty? # false
data.clear # метод clear очищает хеш
data.empty? # true
data.key? :go # true
Важно понимать, что если мы в качестве ключа передадим строку 'go' методу key?
, то метод вернет false
.
Метод merge
позволяет объединить два хеша. Если в целевом хеше обнаружен дубликат, то он будет перезаписан:
with_ruby = data.merge(ruby:'dynamic')
puts whith_ruby
# => { clojure: "dynamic", go: "static", kotlin: "static", ruby: "dynamic" }
new_hash = data.merge(go:'compiled')
puts new_hash
# => { clojure: "dynamic", go: "compiled", kotlin: "static", ruby: "dynamic" }
merge
может принимать блок, который можно использовать например для устранения коллизий:
data = { password: '123456' }
new_data = { password: '123' }
data.merge(new_data) do |key, old_password, new_password|
new_password.length >= 6 ? new_password : old_password
end
В Ruby для работы с хешами есть методы на все случаи жизни, поэтому почаще заглядывайте в документацию и экспериментируйте.
Реализуйте функцию plainify
, которая принимает на вход список песен сгруппированных по имени группы и возвращает плоский список песен, удобный для вывода на экран.
data = {
'Queen' => [
'Bohemian Rhapsody',
"Don't Stop Me Now"
],
'Metallica' => [
'Nothing Else Matters'
],
"Guns N' Roses" => [
'Paradise City',
'November Rain'
],
'AC/DC' => [
'Thunderstruck',
'Back In Black',
'Shoot to Thrill'
]
}
result = plainify data
# [
# { band: 'Queen', song: 'Bohemian Rhapsody' },
# { band: 'Queen', song: "Don't Stop Me Now" },
# { band: 'Metallica', song: 'Nothing Else Matters' },
# { band: "Guns N' Roses", song: 'Paradise City' },
# { band: "Guns N' Roses", song: 'November Rain' },
# { band: 'AC/DC', song: 'Thunderstruck' },
# { band: 'AC/DC', song: 'Back In Black' },
# { band: 'AC/DC', song: 'Shoot to Thrill' }
# ]
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Ваше упражнение проверяется по этим тестам
1# frozen_string_literal: true
2
3require 'test_helper'
4require_relative 'index'
5
6describe 'function' do
7 it 'should works' do
8 data = {
9 'Queen' => [
10 'Bohemian Rhapsody',
11 "Don't Stop Me Now"
12 ],
13 'Metallica' => [
14 'Nothing Else Matters'
15 ],
16 "Guns N' Roses" => [
17 'Paradise City',
18 'November Rain'
19 ],
20 'AC/DC' => [
21 'Thunderstruck',
22 'Back In Black',
23 'Shoot to Thrill'
24 ]
25 }
26 expected = [
27 { band: 'Queen', song: 'Bohemian Rhapsody' },
28 { band: 'Queen', song: "Don't Stop Me Now" },
29 { band: 'Metallica', song: 'Nothing Else Matters' },
30 { band: "Guns N' Roses", song: 'Paradise City' },
31 { band: "Guns N' Roses", song: 'November Rain' },
32 { band: 'AC/DC', song: 'Thunderstruck' },
33 { band: 'AC/DC', song: 'Back In Black' },
34 { band: 'AC/DC', song: 'Shoot to Thrill' }
35 ]
36
37 assert { plainify(data) == expected }
38 end
39end
40
Решение учителя откроется через: