如何用另一个键替换哈希键

Man*_*Das 174 ruby hash ruby-on-rails ruby-on-rails-3

我有一个条件,我得到一个哈希

  hash = {"_id"=>"4de7140772f8be03da000018", .....}
Run Code Online (Sandbox Code Playgroud)

我希望这个哈希为

  hash = {"id"=>"4de7140772f8be03da000018", ......}
Run Code Online (Sandbox Code Playgroud)

PS:我不知道哈希中的键是什么,它们是随机的,每个键带有一个"_"前缀,我不想要下划线

gay*_*vat 672

hash[:new_key] = hash.delete :old_key
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的回应! (69认同)
  • 我经常不喜欢"智能"ruby代码,因为它需要一些时间来分辨它实际上在做什么.另一方面,您的解决方案简单且具有描述性. (10认同)
  • 救了我一对LOC,喜欢它! (8认同)
  • 棒极了 !最好的答案,谢谢! (4认同)
  • 这应该是公认的答案!简单,干净,直截了当! (3认同)
  • 这个答案很优雅,但实际上并没有回答问题。该帖子指出需要替换的键未知...我们只知道它们以下划线开头,我们不知道这些键实际上是什么。 (2认同)
  • 所以这会创建一个新的键/值对,您可以在其中指定新键,并从"hash.delete:old_key"返回的值中获取值,删除使用旧键.哇,我想在某处纹身:-谢谢 (2认同)

gay*_*vat 129

rails Hash有标准方法:

hash.transform_keys{ |key| key.to_s.upcase }
Run Code Online (Sandbox Code Playgroud)

http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys

UPD:ruby 2.5方法

  • deep_transform_keys可用于它:) http://apidock.com/rails/v4.2.1/Hash/deep_transform_keys (5认同)
  • 这是Rails方法,不是标准的.但是答案很好. (4认同)
  • 这是Ruby 2.5中语言的标准部分:https://docs.ruby-lang.org/en/trunk/Hash.html#method-i-transform_keys (3认同)
  • 最后!这正是我搜索的内容! (2认同)

mu *_*ort 38

如果所有键都是字符串并且所有键都有下划线前缀,那么您可以使用以下方法修补哈希值:

h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }
Run Code Online (Sandbox Code Playgroud)

除第一个字符外,该k[1, k.length - 1]位抓取所有内容k.如果你想要一份副本,那么:

new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]
Run Code Online (Sandbox Code Playgroud)

要么

new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }
Run Code Online (Sandbox Code Playgroud)

sub如果您不喜欢k[]用于提取子字符串的表示法,也可以使用:

h.keys.each { |k| h[k.sub(/\A_/, '')] = h[k]; h.delete(k) }
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
Run Code Online (Sandbox Code Playgroud)

并且,如果只有一些键具有下划线前缀:

h.keys.each do |k|
  if(k[0,1] == '_')
    h[k[1, k.length - 1]] = h[k]
    h.delete(k)
  end
end
Run Code Online (Sandbox Code Playgroud)

可以对上面的所有其他变体进行类似的修改,但这两个变体:

Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
Run Code Online (Sandbox Code Playgroud)

没有额外修改的键没有下划线前缀应该没问题.

  • {“_id”=>“4de7140772f8be03da000018”、“_type”=>“工作站”、“created_at”=>“2011-06-02T10:24:35+05:45”、“input_header_ids”=>[]、“line_id” "=>"4de7140472f8be03da000017", "updated_at"=>"2011-06-02T10:24:35+05:45"} (3认同)
  • {“id”=>“4de7140772f8be03da000018”、“type”=>“工作站”、“reated_at”=>“2011-06-02T10:24:35+05:45”、“nput_header_ids”=>[]、“ine_id” "=>"4de7140472f8be03da000017", "pdated_at"=>"2011-06-02T10:24:35+05:45"} (2认同)
  • @Manish:"k"代表"key","v"代表"value","x"代表"我不知道该怎么称呼它,但我被训练为数学家所以我称之为x". (2认同)

Sad*_*tam 14

你可以做

hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
Run Code Online (Sandbox Code Playgroud)

这适用于您的情况!


Dig*_*oss 10

h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你试图使用正则表达式来正确地过滤掉下划线,但你应该知道,在ruby中,与javascript等不同,/ ^ /表示'字符串OR LINE'的开头,/ $ /表示'结束字符串OR LINE'.在这种情况下,密钥不太可能在其中有换行符,但是您应该知道在ruby中使用这两个运算符不仅容易出错,而且在针对注入的验证中使用错误时也非常危险.有关说明,请参见[此处](http://homakov.blogspot.nl/2012/05/saferweb-injects-in-various-ruby.html).希望你不介意传播意识. (4认同)

Swa*_*kar 10

如果我们想要重命名哈希中的特定键,那么我们可以按如下方式执行:
假设我的哈希是 my_hash = {'test' => 'ruby hash demo'}
现在我想用'message'替换'test',然后:
my_hash['message'] = my_hash.delete('test')

  • 我通过谷歌搜索来到这里,想要@ Swapnil的回答.谢谢 (2认同)

Yur*_*kyi 5

对于带有transform_keysdelete_prefix / delete_suffix方法的Ruby 2.5或更新版本:

hash1 = { '_id' => 'random1' }
hash2 = { 'old_first' => '123456', 'old_second' => '234567' }
hash3 = { 'first_com' => 'google.com', 'second_com' => 'amazon.com' }

hash1.transform_keys { |key| key.delete_prefix('_') }
# => {"id"=>"random1"}
hash2.transform_keys { |key| key.delete_prefix('old_') }
# => {"first"=>"123456", "second"=>"234567"}
hash3.transform_keys { |key| key.delete_suffix('_com') }
# => {"first"=>"google.com", "second"=>"amazon.com"}
Run Code Online (Sandbox Code Playgroud)