2016-02-03 3 views
-1

Я хочу хэш, который содержит ints от 1 до 18 в качестве ключей. Я хочу, чтобы хэш выглядеть следующим образом:Можно ли заполнить хэш с помощью цикла `for`?

myHash = Hash.new 
myHash[1] = "free" 
myHash[2] = "free" 
... 
myHash[18] = "free" 

Я хочу знать, если есть более хороший способ сделать это, например, используя for петли. Будет что-то вроде:

myHash = Hash.new 
for i in 1..18 
myHash[i] = "free" 

работы, или это будет просто создать 18 ключей, называемых i?

+2

Что произошло, когда вы пытались запустить выше код? – mcfinnigan

+3

Также имейте в виду, что в Ruby вы можете установить значения по умолчанию для хэша, используя 'myHash = Hash.new ('free') ''. Возможно, это не то, что вам нужно в этом случае, но это хорошо знать. – hirolau

+0

@SCraig Если ваши ключи целые, почему вы хотели бы использовать хэш в первую очередь вместо массива? – bogl

ответ

4

for loops редко используются. Я хотел бы предложить each:

hash = {} 
(1..18).each { |i| hash[i] = 'free' } 
hash 
#=> { 1=>"free", 2=>"free", 3=>"free", 4=>"free", 5=>"free", 6=>"free", 
#  7=>"free", 8=>"free", 9=>"free", 10=>"free", 11=>"free", 12=>"free", 
# 13=>"free", 14=>"free", 15=>"free", 16=>"free", 17=>"free", 18=>"free"} 

Вы также можете передать исходный объект - то есть пустой хэш - в петлю с помощью each_with_object:

hash = (1..18).each_with_object({}) { |i, h| h[i] = 'free' } 

В блоке, второй аргумент h относится к переданному -in hash, поэтому его можно изменить. В конце each_with_object возвращает заполненный хэш.

Другой вариант заключается в использовании map:

hash = (1..18).map { |i| [i, 'free'] }.to_h 

Это создает промежуточный массив [[1, 'free'], [2, 'free'], ...] и преобразует его в хэш затем с помощью Array#to_h.

3

Ваш хэш называется myHash, а не hash. Затем в Ruby мы используем каждый, а не для. И ваша переменная должна быть my_hash, а не myHash. Кроме того, вы пропустили ключевое слово конца для своего. Таким образом:

my_hash = Hash.new 
(1..18).each { |index| my_hash[index] = "free" } 
-2

Да. Это возможно, но ваш вопрос не имеет смысла. У вас должен быть массив, как показано ниже. Для этого есть ряд передовых решений. Но для новичка я бы дал вам это решение.

a =["first","second","third",......] 
h = Hash.new 
a.each_with_index do |value,index| 
    h.merge{index => value} 
end 

Это создало бы полный хеш для вас.

+0

Этот код не работает. – Stefan

+0

Что не работает в этом? –

+1

Ну, 'SyntaxError' предотвращает запуск вашего кода. – Stefan

0

Я не уверен, что вы пытаетесь сделать здесь, но я нашел метод в документации Hash (ruby-doc.org/core-2.2.0/Hash.html), который может быть полезен Вот.

Похоже, вы пытаетесь сделать хеш, возвращая строку «бесплатно», когда вы не определили значение.

Как вы знаете, когда вы помните ключ в хэш, который не был определен, он возвращает ноль:

h = {:foo => bar} 
h[:baz] 
# nil 

Вы можете изменить результат по умолчанию неизвестного ключа с помощью #default

h = {1 => 'Cat', 2 => 'Dog'} 
h.default = 'Free' 
h[1] 
# 'Cat' 
h[4] 
# 'Free' 
2

Вот супер быстрый один лайнер, который не требует ручного цикла, инициализируя массив со счетчиком, задает размер массива для этого и применит блок к каждому индексу. Hash[] затем возьмет массив (массивов) и преобразует его в хэш.i будет с нулем, так что вам нужно использовать i+1

my_hash = Hash[Array.new(18) { |i| [i+1, "free"] }] # Pure Ruby 
my_hash = Array.new(18) { |i| [i+1, "free"] }.to_hash # Only works in Rails 
my_hash = Array.new(18) { |i| [i+1, "free"] }.to_h # Only works in Ruby 2.3 
+0

ok спасибо, как бы я установил имя для этого хэша? –

+0

Я обновил пример кода, чтобы назначить хеш, а также добавил несколько вариантов метода – maniacalrobot

1
myHash = Hash.new 
for i in 1..18 
myhash[i] = "free" 

Ну, просто запустите его. Это приводит к ошибке: syntax error, unexpected end-of-input, expecting keyword_end. Ах да, отсутствует end. Давайте добавим отступ, чтобы мы могли видеть, что внутри цикла, а что нет.

myHash = Hash.new 
for i in 1..18 
    myhash[i] = "free" 
end 

Другая ошибка: in 'block in <main>': undefined local variable or method 'myhash' for main:Object (NameError). Рубин говорит, что не знает myhash. Глупый рубин. myhash - это хэш, мы сказали так на первой строке. О, подождите ... мы назвали его myHash, а не myhash.

myHash = Hash.new 
for i in 1..18 
    myHash[i] = "free" 
end 

Запустить его: никаких ошибок, никакого вывода вообще. Добавьте одну строку для проверки myHash:

myHash = Hash.new 
for i in 1..18 
    myHash[i] = "free" 
end 
p myHash 

И там, myHash: {1=>"free", 2=>"free", 3=>"free", 4=>"free", 5=>"free", 6=>"free", 7=>"free", 8=>"free", 9=>"free", 10=>"free", 11=>"free", 12=>"free", 13=>"free", 14=>"free", 15=>"free", 16=>"free", 17=>"free", 18=>"free"}. более

+1

Умнее Ruby добавит в сообщение об ошибке '' вы имели в виду: 'myHash '?' '. – Stefan

0

Один из способов:

([*1..18].product ["free"]).to_h