Module: Tins::Subhash

Included in:
Hash
Defined in:
lib/tins/subhash.rb

Overview

Tins::Subhash provides methods for creating filtered subsets of hashes based on pattern matching against keys.

The subhash method allows you to extract key-value pairs from a hash that match specified patterns, making it easy to work with subsets of hash data based on naming conventions or other criteria.

Examples:

Basic usage with string patterns

hash = { 'foo' => 1, 'bar' => 2, 'foobar' => 3 }
sub = hash.subhash('foo')
# => { 'foo' => 1, 'foobar' => 3 }

Usage with regular expressions

hash = { 'foo' => 1, 'barfoot' => 2, 'foobar' => 3 }
sub = hash.subhash(/^foo/)
# => { 'foo' => 1, 'foobar' => 3 }

Usage with block for value transformation

hash = { 'foo' => 1, 'bar' => 2, 'foobar' => 3 }
sub = hash.subhash('foo') { |key, value, match_data| value * 2 }
# => { 'foo' => 2, 'foobar' => 6 }

Instance Method Summary collapse

Instance Method Details

#subhash(*patterns) {|key, value, match_data| ... } ⇒ Hash

Create a subhash from this hash containing only key-value pairs where the key matches any of the given patterns.

Patterns can be:

  • Regular expressions (matched against key strings)

  • Strings (exact string matching)

  • Symbols (converted to strings for matching)

  • Any object that implements === operator

Parameters:

  • patterns (Array<Object>)

    One or more patterns to match against keys

Yields:

  • (key, value, match_data)

    Optional block to transform values

Yield Parameters:

  • key (String)

    The original hash key

  • value (Object)

    The original hash value

  • match_data (MatchData, nil)

    Match data when pattern is regex, nil otherwise

Returns:

  • (Hash)

    A new hash containing only matching key-value pairs



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/tins/subhash.rb', line 39

def subhash(*patterns)
  patterns.map! do |pat|
    pat = pat.to_sym.to_s if pat.respond_to?(:to_sym)
    pat.respond_to?(:match) ? pat : pat.to_s
  end
  result =
    if default_proc
      self.class.new(&default_proc)
    else
      self.class.new(default)
    end
  if block_given?
    each do |k, v|
      patterns.each { |pat|
        if pat === k.to_s
          result[k] = yield(k, v, $~)
          break
        end
      }
    end
  else
    each do |k, v|
      result[k] = v if patterns.any? { |pat| pat === k.to_s }
    end
  end
  result
end