【问题标题】:Changing a Hash in ruby using an enumerator使用枚举器更改 ruby​​ 中的哈希
【发布时间】:2013-03-20 19:55:17
【问题描述】:

这是我的示例程序:

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 中。

【问题讨论】:

    标签: ruby hash map block


    【解决方案1】:

    如果你想改变哈希值(如你所愿),只需这样做:

    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 ]
    

    它的工作方式是Enumerable#map 返回一个数组(在本例中是一个包含两个元素键/值对的数组),而Hash.[] 可以将[ [a,b], [c,d] ] 转换为{ a=>b, c=>d }

    你正在做的——hash.map{ … }——将每个键/值对映射到一个新值并创建一个数组……然后对该数组什么都不做。虽然有Array#map! 会破坏性地改变一个数组,但没有等效的Hash#map! 可以在一个步骤中破坏性地改变一个哈希。


    另请注意,如果您想破坏性地改变 Hash(或引用其他可变对象的任何其他对象),您可以在正常迭代期间破坏性地改变这些对象:

    # 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"}
    

    但是,由于您在示例代码中使用符号来表示值 - 并且由于符号是可变的 - 最后的说明并不直接适用于此。

    【讨论】:

      【解决方案2】:

      代替:

      w[1] = correction.chop!.to_sym
      

      尝试直接分配给哈希:

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

      Ruby 创建 w 数组只是为了向您传递键和值。分配给该数组不会改变您的哈希值;它只是改变了那个临时数组。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-04
        • 2013-04-10
        • 1970-01-01
        • 2021-12-07
        • 2015-08-26
        • 2011-05-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多