class MultiHash

This class provides a very simple interface for a hash with multiple keys that reference the same value. This is convenient for lookup tables that have several mappings to a single value, without doing anything particularly gross with Array#include? lookups.

Constants

HASH_METHOD_WHITELIST

Attributes

immutable[RW]
immutable?[RW]

Public Class Methods

[](args) click to toggle source
# File lib/multihash/multihash.rb, line 69
def self.[](args)
  MultiHash.new(Hash[args])
end
new(original_hash={}, immutable=true) click to toggle source

Initialize an immutable multihash with the provided hash as its source. For example, we might want to look up the nation which produces different types of cars:

MultiHash.new (
  %w{Honda Nissan} => :japan,
  %w{Ford Chrysler} => :us,
  'BMW' => :germany
)

@param original_hash [Hash<Array|Object, Object>] the hash to convert into a multihash, with arrays or single objects as keys.

# File lib/multihash/multihash.rb, line 30
def initialize(original_hash={}, immutable=true)
  @_hash = Hash.new(original_hash.default)
  @immutable = immutable

  groups = []

  original_hash.each do |orig_key, value|
    key_array = orig_key.is_a?(Array) && orig_key || [orig_key]
    groups << key_array
    key_array.each { |k| map_value(k, value) }
  end

  store_groups(groups) unless immutable?
end

Public Instance Methods

[]=(key, value)
Alias for: set
grouped() click to toggle source
# File lib/multihash/multihash.rb, line 45
def grouped
  Hash[@_groups.values.map { |g| [g, self[g.first]] }]
end
set(key, value) click to toggle source
# File lib/multihash/multihash.rb, line 49
def set(key, value)
  fail 'Cannot modify an immutable MultiHash!' if immutable?
  split_key_from_group(key)
  map_value(key, value)
end
Also aliased as: []=
set_group(key, value) click to toggle source
# File lib/multihash/multihash.rb, line 56
def set_group(key, value)
  fail 'Cannot modify an immutable MultiHash!' if immutable?
  @_groups[key].each { |k| map_value(k, value) }
end
to_h() click to toggle source
# File lib/multihash/multihash.rb, line 61
def to_h
  @_hash
end
values() click to toggle source
# File lib/multihash/multihash.rb, line 65
def values
  @_values ||= @_hash.values.uniq
end

Private Instance Methods

dirty() click to toggle source
# File lib/multihash/multihash.rb, line 75
def dirty
  @_grouped = nil
  @_values = nil
end
map_value(key, value) click to toggle source
# File lib/multihash/multihash.rb, line 80
def map_value(key, value)
  dirty
  @_hash[key] = value
end
split_key_from_group(key) click to toggle source
# File lib/multihash/multihash.rb, line 85
def split_key_from_group(key)
  former_group = @_groups[key]
  other_groups = @_groups.values - former_group
  new_group = key.is_a?(Array) ? key : [key]
  modified_group = former_group - new_group
  store_groups(other_groups + modified_group + new_group)
end
store_groups(groups) click to toggle source
# File lib/multihash/multihash.rb, line 93
def store_groups(groups)
  @_groups = MultiHash.new(Hash[groups.map { |g| [g, g] }])
end