Class: Hash

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

Overview

:nodoc:

Instance Method Summary collapse

Instance Method Details

#collect_values(key) ⇒ Array

Recursively collects values for a key from nested hashes.

Parameters:

  • key (Object)

    Key to search for.

Returns:

  • (Array)


26
27
28
29
30
31
32
33
34
35
# File 'lib/extensions/deep_find.rb', line 26

def collect_values(key)
  result = [self[key]]
  each_value do |value|
    values = value.is_a?(Array) ? value : [value]
    values.each do |v|
      result << v.deep_find(key) if v.is_a?(Hash)
    end
  end
  result
end

#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

  • uniq: (Boolean) (defaults to: true)

Returns:

  • (Object)

    output depends on key value



9
10
11
12
13
14
15
16
17
# File 'lib/extensions/deep_find.rb', line 9

def deep_find(key, uniq: true)
  result = collect_values(key)
  result.compact!
  result.delete_if { |i| i.is_a?(Array) && i.empty? }
  result.uniq! if uniq
  return nil if result.empty?

  result.size == 1 ? result.first : result
end