Ruby Hash leaves (leafs)

Get all leaves of a Hash (like recursive values).

Usage
{:x => 1, :y => {:z => 2}}.leaves == [1,2]

Code

class Hash
  # {'x'=>{'y'=>{'z'=>1,'a'=>2}}}.leaves == [1,2]
  def leaves
    leaves = []

    each_value do |value|
      value.is_a?(Hash) ? value.leaves.each{|l| leaves << l } : leaves << value
    end

    leaves
  end
end

3 thoughts on “Ruby Hash leaves (leafs)

  1. I have several remarks regarding the code.

    1. The commented out line has a typo (there are 3 opening braces and only 2 closing).

    2. It’s better to use “leaves” instead of “leafs”.

    3. `each do |key,value|` block don’t use `key` at all. Replace it with `each_value do |value|`

    4. `value.respond_to?(:leaves)` looks more natural and idiomatic than `value.is_a?(Hash)`.

    5. The whole method actually is an incarnation of `Enumerable#flat_map`. So it would be much shorter to rewrite it. See my final version:

    • 1: duh
      2: we had leaves at the start and someone said “lets look into the dictionary…” but google confirms leaves is the better choise 🙂
      3: yep, should a bit be faster :>
      4: seems about right
      5: is only 1.9, so ill keep the original concat

      Thanks for the help!

  2. Implementation that retrieves leaf values from a hash of both hashes and arrays:

    def leaves(collection)
    leaves = []

    if collection.is_a?(Hash)
    collection.each_value { |l| leaves << leaves(l) }
    elsif collection.is_a?(Array)
    collection.each { |l| leaves << leaves(l) }
    else
    leaves << collection
    end

    leaves.flatten
    end

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s