我希望从这个
开始{'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}
答案 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