我希望从这个
{'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}
您可以过滤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
(即您想要的键)显式驱动的附加优势,这可能(也可能不)对您和维护您的代码的人很重要。
一个简单的解决方案是同时做每一个并添加另一个哈希:
result = {}
product = {'productId' => '1234', 'unwantedKey' => 'nope'}
product.each do |key,value|
if api_keys.include?(k)
result[key.underscore.to_sym] = value
end
end
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
您可以考虑的一件事是是否要避免delete传递。
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
这个问题很老了,但是既然我偶然发现了它,其他人可能也会这样。这是我的看法,假设activessupport核心扩展加载,因为你正在使用String#underscore
:
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