[ruby-on-rails] 해시 / YAML에서 빈 요소를 모두 제거 하시겠습니까?

중첩 된 해시 또는 YAML 파일에서 빈 요소 (빈 목록 항목)를 모두 제거하려면 어떻게해야합니까?



답변

이처럼 해시에 간단한 방법을 추가 할 수 있습니다

class Hash
  def compact
    delete_if { |k, v| v.nil? }
  end
end

또는 재귀를 지원하는 버전

class Hash
  def compact(opts={})
    inject({}) do |new_hash, (k,v)|
      if !v.nil?
        new_hash[k] = opts[:recurse] && v.class == Hash ? v.compact(opts) : v
      end
      new_hash
    end
  end
end


답변

Rails 4.1에는 Hash # compactHash # compact! 루비 Hash클래스 의 핵심 확장으로 . 다음과 같이 사용할 수 있습니다.

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
# => {}

헤딩 :이 구현은 재귀 적이 지 않습니다. 호기심으로 그들은 성능상의 이유 #select대신에 그것을 사용하여 구현했습니다 #delete_if. 벤치 마크는 여기를 참조 하십시오 .

Rails 3 앱으로 백 포트하려는 경우 :

# 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


답변

hsh.delete_if를 사용하십시오 . 구체적인 경우에는 다음과 같습니다.hsh.delete_if { |k, v| v.empty? }


답변

루비 2.4+을 사용하는 경우 호출 할 수 있습니다 compactcompact!

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


답변

이것은 빈 해시도 삭제합니다.

swoop = Proc.new { |k, v| v.delete_if(&swoop) if v.kind_of?(Hash);  v.empty? }
hsh.delete_if &swoop


답변

Hash # reject 를 사용 하여 루비 해시에서 빈 키 / 값 쌍을 제거 수 있습니다 .

# Remove empty strings
{ a: 'first', b: '', c: 'third' }.reject { |key,value| value.empty? }
#=> {:a=>"first", :c=>"third"}

# Remove nil
{a: 'first', b: nil, c: 'third'}.reject { |k,v| v.nil? }
# => {:a=>"first", :c=>"third"}

# Remove nil & empty strings
{a: '', b: nil, c: 'third'}.reject { |k,v| v.nil? || v.empty? }
# => {:c=>"third"}


답변

해시와 배열 모두에서 작동

module Helpers
  module RecursiveCompact
    extend self

    def recursive_compact(hash_or_array)
      p = proc do |*args|
        v = args.last
        v.delete_if(&p) if v.respond_to? :delete_if
        v.nil? || v.respond_to?(:"empty?") && v.empty?
      end

      hash_or_array.delete_if(&p)
    end
  end
end

누군가의 답변에 따라 PS를 찾을 수 없습니다

사용법- Helpers::RecursiveCompact.recursive_compact(something)