Removing all empty elements from a hash / YAML?

前端 未结 20 1577
礼貌的吻别
礼貌的吻别 2020-12-07 15:35

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

相关标签:
20条回答
  • 2020-12-07 15:48

    Could be done with facets library (a missing features from standard library), like that:

    require 'hash/compact'
    require 'enumerable/recursively'
    hash.recursively { |v| v.compact! }
    

    Works with any Enumerable (including Array, Hash).

    Look how recursively method is implemented.

    0 讨论(0)
  • 2020-12-07 15:48

    Try this to remove nil

    hash = { a: true, b: false, c: nil }
    => {:a=>true, :b=>false, :c=>nil}
    hash.inject({}){|c, (k, v)| c[k] = v unless v.nil?; c}
    => {:a=>true, :b=>false}
    
    0 讨论(0)
  • 2020-12-07 15:52

    Here is something I have:

    # recursively remove empty keys (hashes), values (array), hashes and arrays from hash or array
    def sanitize data
      case data
      when Array
        data.delete_if { |value| res = sanitize(value); res.blank? }
      when Hash
        data.delete_if { |_, value| res = sanitize(value); res.blank? }
      end
      data.blank? ? nil : data
    end
    
    0 讨论(0)
  • 2020-12-07 15:53
    class Hash   
      def compact
        def _empty?(val)
          case val
          when Hash     then val.compact.empty?
          when Array    then val.all? { |v| _empty?(v) }
          when String   then val.empty?
          when NilClass then true
          # ... custom checking 
          end
        end
    
        delete_if { |_key, val| _empty?(val) }   
      end 
    end
    
    0 讨论(0)
  • 2020-12-07 15:58

    If you're using Ruby 2.4+, you can call compact and compact!

    h = { a: 1, b: false, c: nil }
    h.compact! #=> { a: 1, b: false }
    

    https://ruby-doc.org/core-2.4.0/Hash.html#method-i-compact-21

    0 讨论(0)
  • 2020-12-07 15:58

    I made a deep_compact method for this that recursively filters out nil records (and optionally, blank records as well):

    class Hash
      # Recursively filters out nil (or blank - e.g. "" if exclude_blank: true is passed as an option) records from a Hash
      def deep_compact(options = {})
        inject({}) do |new_hash, (k,v)|
          result = options[:exclude_blank] ? v.blank? : v.nil?
          if !result
            new_value = v.is_a?(Hash) ? v.deep_compact(options).presence : v
            new_hash[k] = new_value if new_value
          end
          new_hash
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题