У меня есть массив и функция, которая возвращает значение, заданное значением. В конечном итоге я хочу создать хэшмап, в котором значения массива будут ключевым значением, а результат функции f(key_value) - значением. Есть ли чистый, простой способ, похожий на each/map из Array, чтобы сделать это с помощью блока?
То есть что-то, что эквивалентно
hsh = {}
[1,2,3,4].each do |x|
hsh[x] = f(x)
end
но выглядит более похожим на это, в том смысле, что оно простое и в одну строку?
results = array.map { | x | f(x) }
Обратите внимание, что начиная с Ruby 2.1.0 вы можете также использовать массив#to_h, такой:
в
[1,2,3,4].map{ |x| [x, f(x)] }.to_h
Вы также можете определить функцию как значение хэша по умолчанию:
hash = Hash.new {|hash, key| hash[key] = f(key) }
Тогда при поиске значения хэш будет вычислять и сохранять его на лету.
hash[10]
hash.inspect #=> { 10 => whatever_the_result_is }
Вам нужен each_with_object
.
def f x
x * 2
end
t = [1, 2, 3, 4].each_with_object({}) do |x, memo|
memo[x] = f(x)
end
t # => {1=>2, 2=>4, 3=>6, 4=>8}
Еще один:
t2 = [1, 2, 3, 4].map{|x| [x, f(x)]}
Hash[t2] # => {1=>2, 2=>4, 3=>6, 4=>8}
Используя фасеток' Маш (способ конвертировать перечисляемые в хэши):
[1, 2, 3, 4].mash { |x| [x, f(x)] }
Из Ruby 2.1:
[1, 2, 3, 4].map { |x| [x, f(x)] }.to_h
Руби 2.6.0 позволяет передавая блок на to_h`-метод. Это позволяет еще более короткий синтаксис для создания хэша из массива:
[1, 2, 3, 4].to_h { |x| [x, f(x)] }
Вы'вновь ищу уменьшить()|вколоть (метод)
:
elem = [1,2,3,4]
h = elem.reduce({}) do |res, x|
res[x] = x**2
res
end
puts h
Аргумент к сокращению ({})- начальное значение промежуточного объекта, который передается в блок
РЭСпеременной. В каждой итерации мы'повторное добавление новых ключевых пара
: значениек
РЭС` хэш и возврата хэш используется в следующей итерации.
Описанный выше метод precomputes очень практичный хэш-квадратов значений:
{1=>1, 2=>4, 3=>9, 4=>16}