如何更改哈希值?

118 ruby syntax hash

我想value用哈希替换每个哈希value.some_method.

例如,对于给定的简单哈希:

{"a" => "b", "c" => "d"}` 
Run Code Online (Sandbox Code Playgroud)

每个值都应该是.upcased,所以它看起来像:

{"a" => "B", "c" => "D"}
Run Code Online (Sandbox Code Playgroud)

我试过#collect,#map但总是把数组拿回来.有一种优雅的方式来做到这一点?

UPDATE

该死的,我忘记了:哈希是一个不应该改变的实例变量.我需要一个带有更改值的新哈希,但是不希望显式定义该变量,然后遍历填充它的哈希.就像是:

new_hash = hash.magic{ ... }
Run Code Online (Sandbox Code Playgroud)

kch*_*kch 206

my_hash.each { |k, v| my_hash[k] = v.upcase } 
Run Code Online (Sandbox Code Playgroud)

或者,如果您更喜欢非破坏性地执行此操作,并返回新的哈希而不是修改my_hash:

a_new_hash = my_hash.inject({}) { |h, (k, v)| h[k] = v.upcase; h } 
Run Code Online (Sandbox Code Playgroud)

最后一个版本还有一个额外的好处,你也可以转换键.

  • @Adam @kch`his_with_object`是一个更方便的`inject`版本,当你不想用散列结束块时:`my_hash.each_with_object({}){|(k,v),h | h [k] = v.upcase}` (34认同)
  • 第一个建议不合适; 在迭代时修改可枚举元素会导致未定义的行为 - 这在其他语言中也是有效的.这是Matz的回复(他回复使用数组的例子,但答案是通用的):http://j.mp/tPOh2U (24认同)
  • 还有一种非常简洁的语法可以将对列表转换为哈希,因此您可以编写`a_new_hash = Hash [my_hash.map {| k,v | [k,v.upcase]}]` (6认同)
  • @Marcus我同意一般应该避免这种修改.但在这种情况下,它可能是安全的,因为修改不会改变未来的迭代.现在,如果分配了另一个密钥(不是传递给该块的密钥),那么就会出现问题. (4认同)
  • 使用Ruby 2,您可以编写`.to_h` (2认同)
  • 请参阅下面 @potashin 的答案,以获得更好的、现代的解决方案。 (2认同)

pot*_*hin 88

由于ruby 2.4.0您可以使用本机Hash#transform_values方法:

hash = {"a" => "b", "c" => "d"}
new_hash = hash.transform_values(&:upcase)
# => {"a" => "B", "c" => "D"}
Run Code Online (Sandbox Code Playgroud)

还有破坏性的Hash#transform_values!版本.

  • 很棒,它还带有导轨4.2.1 https://apidock.com/rails/v4.2.1/Hash/transform_values (4认同)

End*_*del 33

您可以收集值,并再次将其从Array转换为Hash.

像这样:

config = Hash[ config.collect {|k,v| [k, v.upcase] } ]
Run Code Online (Sandbox Code Playgroud)


Kon*_*che 23

这样做:

my_hash.each_with_object({}) { |(key, value), hash| hash[key] = value.upcase }
Run Code Online (Sandbox Code Playgroud)

inject与优势相反,您无需在块内再次返回哈希.


Chr*_*ett 10

试试这个功能:

h = {"a" => "b", "c" => "d"}
h.each{|i,j| j.upcase!} # now contains {"a" => "B", "c" => "D"}.
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但应该注意的是,它只适用于当j具有对自身起作用的破坏性方法时.所以它无法处理一般的value.some_method案例. (5认同)

sch*_*jos 10

ActiveSupport v4.2.0中有一种方法.它被调用transform_values,基本上只是为每个键值对执行一个块.

因为他们正在这样做,each我认为没有比循环更好的方法了.

hash = {sample: 'gach'}

result = {}
hash.each do |key, value|
  result[key] = do_stuff(value)
end
Run Code Online (Sandbox Code Playgroud)

更新:

从Ruby 2.4.0开始,你就可以使用#transform_values#transform_values!.