Ruby:有没有更有效的方法将哈希键的子集转换为下划线符号?

时间:2011-08-01 03:33:20

标签: ruby-on-rails ruby ruby-on-rails-3

我希望从这个

开始
{'productId' => '1234', 'unwantedKey' => 'nope'}

{:product_id => '1234'}

假设在这个例子中我只想要productId键/值。在下面的代码中,api_key返回一个我想从哈希中提取的键数组。有更好的方法吗?

product.delete_if { |k, v| !api_keys.include? k }.inject({}){|memo,(k,v)| memo[k.underscore.to_sym] = v; memo}

5 个答案:

答案 0 :(得分:3)

您可以filter the api_keys然后使用each_with_object来构建哈希切片:

slice = api_keys.find_all { |k| h.has_key?(k) }.each_with_object({ }) { |k,o| o[k.underscore.to_sym] = h[k] }
如果你是迭代而不是减少,那么

each_with_object通常是比inject更好的选择。

假设:

h        = { 'productId' => '1234', 'unwantedKey' => 'nope' }
api_keys = [ 'productId' ]

上述事项:

slice = { :product_id => '1234' }

find_all / each_with_object还具有被api_keys明确驱动的额外优势(即您想要的密钥),并且可能(或可能不)对您和您来说很重要人们维护你的代码。

答案 1 :(得分:2)

一个简单的解决方案是执行每个操作并同时添加另一个哈希:

result  = {}
product = {'productId' => '1234', 'unwantedKey' => 'nope'}
product.each do |key,value|
  if api_keys.include?(k)
    result[key.underscore.to_sym] = value
  end
end

答案 2 :(得分:1)

api_keys = ['productId'] # etc...
product = {'productId' => '1234', 'unwantedKey' => 'nope'}

result = product.inject({}) do |hash, (key, value)|
  hash[key.underscore.to_sym] = value if api_keys.include?(key); hash
end

答案 3 :(得分:1)

你能想到的一件事是你是否想要避免删除通行证。

final = {}
initial.each do |k, v|
  final[k.underscore.sym] = v if api_keys.include?(k)
end

final = initial.inject({}) do |h, (k,v)|
  h[k.underscore.sym] = v if api_keys.include?(k)
  h
end 

答案 4 :(得分:0)

这个问题已经很久了,但是因为我偶然发现了,其他人也可能。这是我的看法,假设您使用String#underscore后加载了ActiveSupport核心扩展程序:

hash = {'productId' => '1234', 'unwantedKey' => 'nope'}
api_keys = ['productId']

filtered = hash.slice(*api_keys).each.with_object({}) do |(k,v),h|
  h[k.underscore.to_sym] = v
end