Removing all empty elements from a hash / YAML?

前端 未结 20 1703
礼貌的吻别
礼貌的吻别 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 16:00

    Ruby's Hash#compact, Hash#compact! and Hash#delete_if! do not work on nested nil, empty? and/or blank? values. Note that the latter two methods are destructive, and that all nil, "", false, [] and {} values are counted as blank?.

    Hash#compact and Hash#compact! are only available in Rails, or Ruby version 2.4.0 and above.

    Here's a non-destructive solution that removes all empty arrays, hashes, strings and nil values, while keeping all false values:

    (blank? can be replaced with nil? or empty? as needed.)

    def remove_blank_values(hash)
      hash.each_with_object({}) do |(k, v), new_hash|
        unless v.blank? && v != false
          v.is_a?(Hash) ? new_hash[k] = remove_blank_values(v) : new_hash[k] = v
        end
      end
    end
    

    A destructive version:

    def remove_blank_values!(hash)
      hash.each do |k, v|
        if v.blank? && v != false
          hash.delete(k)
        elsif v.is_a?(Hash)
          hash[k] = remove_blank_values!(v)
        end
      end
    end
    

    Or, if you want to add both versions as instance methods on the Hash class:

    class Hash
      def remove_blank_values
        self.each_with_object({}) do |(k, v), new_hash|
          unless v.blank? && v != false
            v.is_a?(Hash) ? new_hash[k] = v.remove_blank_values : new_hash[k] = v
          end
        end
      end
    
      def remove_blank_values!
        self.each_pair do |k, v|
          if v.blank? && v != false
            self.delete(k)
          elsif v.is_a?(Hash)
            v.remove_blank_values!
          end
        end
      end
    end
    

    Other options:

    • Replace v.blank? && v != false with v.nil? || v == "" to strictly remove empty strings and nil values
    • Replace v.blank? && v != false with v.nil? to strictly remove nil values
    • Etc.

    EDITED 2017/03/15 to keep false values and present other options

提交回复
热议问题