【问题标题】:How to duplicate a Ruby hash based on existing key names?如何根据现有的键名复制 Ruby 哈希?
【发布时间】:2014-09-08 20:01:20
【问题描述】:

如何根据原始键名重命名 Ruby 哈希中的所有键,例如,为所有键添加前缀?

hash = { foo: "bar", test: "blah", hello: "world" }

# do something to `hash`
=> { pre_foo: "bar", pre_test: "blah", pre_hello: "world" }

我会使用Hash#map 或类似的东西吗?


我在“How to change all the keys of a hash by a new set of given keys?”的帮助下得到了一些帮助,修改它以访问当前密钥:

Hash[hash.map {|k, v| ["pre_#{k}".to_sym, v] }]

有没有更好的办法?

【问题讨论】:

  • 不要重命名它们,创建一个新的哈希。

标签: ruby hash


【解决方案1】:
hash.map {|k, v| ["pre_#{k}".to_sym, v] }.to_h

这个想法似乎是我认为最好的。但请确保您的 Ruby 版本支持to_h

【讨论】:

  • 我打算接受我编辑的答案,但不得不等待一天,这是我采用的方法,它是最干净、最好的一个班轮
【解决方案2】:

你也可以这样做:

hash = { foo: "bar", test: "blah", hello: "world" }
def add_prefix(hsh, key)
  hsh.each_with_object({}) do |(k,v),h|
     h["#{key}#{k}".to_sym] = v
  end
end

add_prefix(hash, 'pre_')
# => {:pre_foo=>"bar", :pre_test=>"blah", :pre_hello=>"world"}

【讨论】:

  • 你好,奥雅纳。两个建议:定义为 Hash 方法,因为 OP 想要 hash.add_prefix... 并摆脱所有丑陋的东西。
  • 我将其编辑为单行,而不是使用函数,看起来更干净:hash.each_with_object({}) {|(k,v),h| h["pre_#{k}".to_sym] = v }
  • @CarySwoveland 我已编辑。但是monkey patching不是一个好主意,也不是所有人都喜欢它。所以..我没有:-)
  • Arup,我完全同意你的观点,并且看到 OP 对这里的猴子补丁不感兴趣。
  • h["#{key}k".to_sym] 不会返回您显示的结果。复制/粘贴工作代码及其结果是个好主意。
【解决方案3】:

如果您想“重命名”键,而不是创建新的哈希,最简单的方法是同时添加新键并删除现有键(不能直接重命名键):

def add_prefix(hash, prefix)
  hash.keys.each { |k| hash[(prefix+k.to_s).to_sym] = hash.delete(k) }
end

hash = { foo: "bar", test: "blah", hello: "world" }

add_prefix(hash, "pre_")
  #=> {:pre_foo=>"bar", :pre_test=>"blah", :pre_hello=>"world"}
hash
  #=> {:pre_foo=>"bar", :pre_test=>"blah", :pre_hello=>"world"}

【讨论】:

  • 你说得对,我确实有add_prefix,我的意思是更多的伪代码。我宁愿不猴子补丁哈希,不过谢谢你的回答!
  • 不需要显示“编辑”。如果它很重要,我们可以看到变化。如果您担心显示修订历史记录,文本中一个简单的--- 将为您提供一个水平条,可以很好地描述内容。
  • Sucker,我根据您的评论进行了编辑。 @theTinMan,感谢您的建议。
【解决方案4】:

修改自“How to change all the keys of a hash by a new set of given keys?

hash.map {|k, v| ["pre_#{k}".to_sym, v] }.to_h

也许有更好的方法来做到这一点。转换为数组,然后再转换回哈希似乎有点矫枉过正。

【讨论】:

  • 这取决于您的 Ruby 版本。 to_h 已添加到 Array,它将名称/值对数组转换为哈希。 hash.map{ |k, v| ["pre_#{k}".to_sym, v] }.to_h # => {:pre_foo=>"bar", :pre_test=>"blah", :pre_hello=>"world"}map 会将其转换为名称/值数组,因此必须进行转换。
  • 我正在考虑使用它,因为它更短、更具可读性,并且在对其进行基准测试(哈希中的 10000 个键)之后,速度似乎几乎快了两倍,尽管没什么大不了的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 2017-12-18
  • 2011-05-08
  • 2021-11-03
  • 2011-07-01
  • 1970-01-01
  • 2015-08-03
相关资源
最近更新 更多