2013-03-30 156 views
2

在這裏,紅寶石更改哈希是我的示例程序:使用枚舉

what = {:banana=>:fruit, :pear=>:fruit, :sandal=>:fruit, :panda=>:fruit, :apple=>:fruit} 

what.map do |w| 
    p "is this right?" 
    awesome_print w 
    fix = gets 
    fix.chop! 
    if (fix == "N") 
     p "Tell me what it should be" 
     correction = gets 
     w[1] = correction.chop!.to_sym 
    end 
    p w 
end 

我運行它,我得到的(包括我輸入)這樣的:

"is this right?" 
[ 
    [0] :banana, 
    [1] :fruit 
] 
Y 
[:banana, :fruit] 
"is this right?" 
[ 
    [0] :pear, 
    [1] :fruit 
] 
Y 
[:pear, :fruit] 
"is this right?" 
[ 
    [0] :sandal, 
    [1] :fruit 
] 
N 
"Tell me what it should be" 
footwear 
[:sandal, :footwear] 
"is this right?" 
[ 
    [0] :panda, 
    [1] :fruit 
] 
N 
"Tell me what it should be" 
animal 
[:panda, :animal] 
"is this right?" 
[ 
    [0] :apple, 
    [1] :fruit 
] 
Y 
[:apple, :fruit] 
=> [[:banana, :fruit], [:pear, :fruit], [:sandal, :footwear], [:panda, :animal], [:apple, :fruit]] 
>> what 
=> {:banana=>:fruit, :pear=>:fruit, :sandal=>:fruit, :panda=>:fruit, :apple=>:fruit} 

我的問題是如何能我改變哈希?當我運行程序時,irb告訴我每個枚舉元素都被處理,但結果不會保存在我的散列表what中。如果你想創建一個新的哈希

my_hash.each do |key,value|  # map would work just as well, but not needed 
    my_hash[key] = some_new_value  
end 

,不改變原:

回答

5

如果你想變異到位哈希(你似乎想),只要做到這一點

new_hash = Hash[ my_hash.map do |key,value| 
    [ key, new_value ] 
end ] 

此工作的方式是,Enumerable#map返回一個數組(在這種情況下,兩個元件的鍵/值對的陣列),以及Hash.[]可以把[ [a,b], [c,d] ]{ a=>b, c=>d }

你在做什麼 - hash.map{ … } - 將每個鍵/值對映射到一個新值並創建一個數組...然後對該數組不做任何操作。雖然Array#map!這將破壞性地改變陣列,但沒有等效的Hash#map!在單個步驟中破壞性地改變散列。


還要注意的是,如果你想破壞性變異散列或引用其他可變對象,在地方,你可以只破壞性正常的迭代過程中發生變異的那些對象的任何其他對象:

# A simple hash with mutable strings as values (not symbols) 
h = { a:"zeroth", b:"first", c:"second", d:"third" } 

# Mutate each string value 
h.each.with_index{ |(char,str),index| str[0..-3] = index.to_s } 

p h #=> {:a=>"0th", :b=>"1st", :c=>"2nd", :d=>"3rd"} 

然而,因爲你在示例代碼中使用的是符號 - 因爲符號是而不是可變 - 這個最後的註釋並不直接適用於那裏。

1

相反的:

w[1] = correction.chop!.to_sym 

儘量分配給直接哈希:

what[w[0]] = correction.chop!.to_sym 

紅寶石創建w陣只是爲了打發你的鍵和值。分配給該數組不會改變你的散列;它只是改變那個臨時陣列。