Proposal: Hash#deep_values

Hello folks :wave:

TL;DR - Add a Hash#deep_values extension

This is in fact my first rodeo here so bear with me if this is not the right place to propose this. I have the need to fetch all the leaf values of a deeply nested hash:

assessment = {
  title: 'my assessment',
  questions: {
    1234 => {
      title: 'first question',
      answer: 'first answer',
    },
    5678 => {
      title: 'second question',
      question: 'second answer'
    }
  }
}

assessment.deep_values # ['my assessment', 'first question', 'first answer', 'second question', 'second answer']

I am currently solving this need in my controller with the following:

def deep_values
  values = [] 
  
  assessment.deep_transform_values { |value| values << value } 
  
  values
end

This works as expected, however it seems to me that we are dealing with a pretty generic pattern here and it would make more sense to just be able to call assessment.deep_values:

class Hash 
  def deep_values
    _deep_values(self)
  end

  private

  def _deep_values(object)
    case object
    when Hash
      object.values.flat_map { |value| _deep_values(value) }
    when Array
      object.flat_map { |element| _deep_values(element) }
    else
      [object]
    end
  end
end

I know the official docs mention that most ActiveSupport extension proposals are rejected, however maybe this is one of those exceptions…

Appreciate your feedback!

2 Likes