Removing all empty elements from a hash / YAML?

How would I go about removing all empty elements (empty list items) from a nested Hash or YAML file?


Solution 1:

Rails 4.1 added Hash#compact and Hash#compact! as a core extensions to Ruby's Hash class. You can use them like this:

hash = { a: true, b: false, c: nil }
hash.compact                        
# => { a: true, b: false }
hash                                
# => { a: true, b: false, c: nil }
hash.compact!                        
# => { a: true, b: false }
hash                                
# => { a: true, b: false }
{ c: nil }.compact                  
# => {}

Heads up: this implementation is not recursive. As a curiosity, they implemented it using #select instead of #delete_if for performance reasons. See here for the benchmark.

In case you want to backport it to your Rails 3 app:

# config/initializers/rails4_backports.rb

class Hash
  # as implemented in Rails 4
  # File activesupport/lib/active_support/core_ext/hash/compact.rb, line 8
  def compact
    self.select { |_, value| !value.nil? }
  end
end

Solution 2:

Use hsh.delete_if. In your specific case, something like: hsh.delete_if { |k, v| v.empty? }