Class: Hash

Inherits:
Object show all
Defined in:
lib/extensions/deep_find.rb

Overview

:nodoc:

Instance Method Summary collapse

Instance Method Details

#deep_find(key, uniq: true) ⇒ Object

TODO:

change uniq true to uniq false

Hash#deep_find -> value

This method is an extension for Hash core class to search for a value of a key in N-nested hash. It provides search for multiple values if key appears more than once. For e.g.:

If values are identical, they will be returned in a single copy. You can disable this feature with special param uniq, which is true by default. For e.g.:

Examples:

musicians = { "Travis Scott" => { "28" => ["Highest in the Room", "Franchise"] },
            "Adele" => { "19" => ["Day Dreamer", "Best for Last"] },
            "Ed Sheeran" => { "28" => ["Shape of You", "Castle on the Hill"] } }
musicians.deep_find("19") #=> ["Day Dreamer", "Best for Last"]
musicians.deep_find("Adele") #=> {"19"=>["Day Dreamer", "Best for Last"]}
musicians.deep_find("28") #=> [["Highest in the Room", "Franchise"], ["Shape of You", "Castle on the Hill"]]
h = {"a" => "b", "c" => {"a" => "b"}}
h.deep_find("a") #=> "b", instead ["b", "b"]

Parameters:

  • key (Object)

    A key, which value should be found

  • uniq (FalseClass) (defaults to: true)

    A flag to make values unique in an array

Returns:

  • (Object)

    output depends on key value



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/extensions/deep_find.rb', line 27

def deep_find(key, uniq: true)
  result = []
  result << self[key]
  each_value do |hash_value|
    values = hash_value.is_a?(Array) ? hash_value : [hash_value]
    values.each do |value|
      result << value.deep_find(key) if value.is_a? Hash
    end
  end
  result = result.compact.delete_if do |i|
    i.is_a?(Array) && i.empty?
  end
  result.uniq! if uniq
  result.size == 1 ? result.first : result
end