假设:
data = {:a => 'A', :b => '', :c => 'C', :d => ''}
目标:如果键值为空字符串,则删除键:c
和:d
。但是,:a
和:b
即使其值为空字符串也应保留。在上面的示例中,最终结果应为:
{:a => 'A', :b => '', :c => 'C'}
目前的做法:
if data[:c] == ''
data.delete(:c)
end
if data[:d] == ''
data.delete(:d)
end
有没有更好的方法来获得相同的结果? (实际上,类型c和d的键大于10,导致if
一长串检查。)
答案 0 :(得分:3)
您可以使用Hash#delete_if
方法
unwanted_keys = [:c, :d]
hash = {:a => 'A', :b => '', :c => 'C', :d => ''}
hash.delete_if{ |k,v| unwanted_keys.include?(k) && v.blank? }
希望有所帮助!
答案 1 :(得分:2)
您可以使用Enumerable#each_with_object
根据您的条件动态构建新哈希:
data.each_with_object({}) do |(k, v), h|
h[k] = v unless %i(c d).include?(k) && v == ''
end
#=> {:a=>"A", :b=>"", :c=>"C"}
在评论中提到@user000001,另一个不错的选择是使用Enumerable#reject
:
data.reject { |k, v| %i(c d).include?(k) && v == '' }
答案 2 :(得分:1)
你总是可以遍历键列表
KEYS_TO_DELETE_IF_BLANK = %i[c d]
KEYS_TO_DELETE_IF_BLANK.each do |key|
data.delete(key) if data[key].blank?
end
答案 3 :(得分:0)
您可以使用select
使用值
data = {:a => 'A', :b => '', :c => 'C', :d => ''}
data.select() {|k, v| v.present? || k == :a || k == :b }
# => => {:a=>"A", :b=>"", :c=>"C"}
答案 4 :(得分:0)
您还可以使用delete if
:
data = { :a => 'A', :b => '', :c => 'C', :d => '' }
data.delete_if { |k, value| %i(c d).include?(k) && value.to_s.strip == '' }