使用枚举器更改ruby中的哈希

使用枚举器更改ruby中的哈希,ruby,hash,map,block,Ruby,Hash,Map,Block,以下是我的示例程序: 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 i

以下是我的示例程序:

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
我运行它,我得到这个(包括我的输入):


我的问题是如何更改哈希?irb告诉我,当我运行程序时,每个枚举元素都会被处理,但结果不会保存在我的哈希
what

中。如果您想在适当的位置对哈希进行变异(如您所希望的),只需执行以下操作:

my_hash.each do |key,value|       # map would work just as well, but not needed
  my_hash[key] = some_new_value    
end
如果要创建新哈希,而不更改原始哈希,请执行以下操作:

new_hash = Hash[ my_hash.map do |key,value|
  [ key, new_value ]
end ]
其工作方式是返回一个数组(在本例中是两个元素键/值对的数组),并可以将
[[a,b],[c,d]
转换为
{a=>b,c=>d}

您所做的-
hash.map{…}
-是将每个键/值对映射到一个新值并创建一个数组…然后对该数组不做任何操作。还有
Array#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"}
但是,由于您使用符号表示示例代码中的值,并且符号不可更改,因此最后一个注释不会直接应用于该示例代码。

而不是:

w[1] = correction.chop!.to_sym
尝试直接分配到哈希:

what[w[0]] = correction.chop!.to_sym
Ruby创建
w
数组只是为了传递键和值。分配给该数组不会改变哈希值;它只是在更改临时数组

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