Class: NestedMultimap
Overview
NestedMultimap allows values to be assoicated with a nested set of keys.
Direct Known Subclasses
Instance Method Summary collapse
-
#<<(value) ⇒ Object
call-seq: multimap << obj => multimap.
-
#[](*args) ⇒ Object
call-seq: multimap => value multimap[key1, key2, key3] => value.
-
#containers_with_default ⇒ Object
call-seq: multimap.containers_with_default => array.
-
#each_association ⇒ Object
call-seq: multimap.each_association { |key, container| block } => multimap.
-
#each_container_with_default ⇒ Object
call-seq: multimap.each_container_with_default { |container| block } => map.
-
#height ⇒ Object
call-seq: multimap.height => fixnum.
-
#inspect ⇒ Object
:nodoc:.
-
#store(*args) ⇒ Object
(also: #[]=)
call-seq: multimap = value => value multimap.store(*keys, value) => value.
Methods inherited from Multimap
[], #containers, #delete, #each, #each_container, #each_key, #each_pair, #each_value, #freeze, #has_value?, #index, #initialize, #initialize_copy, #invert, #keys, #merge, #replace, #select, #size, #to_a, #to_hash, #update, #values
Constructor Details
This class inherits a constructor from Multimap
Instance Method Details
#<<(value) ⇒ Object
call-seq:
multimap << obj => multimap
Pushes the given object on to the end of all the containers.
map = NestedMultimap["a" => [100], "b" => [200, 300]]
map << 300
map["a"] #=> [100, 300]
map["c"] #=> [300]
46 47 48 49 50 |
# File 'lib/nested_multimap.rb', line 46 def <<(value) hash_each_pair { |_, container| container << value } self.default << value self end |
#[](*args) ⇒ Object
call-seq:
multimap[*keys] => value
multimap[key1, key2, key3] => value
Retrieves the value object corresponding to the *keys object.
58 59 60 61 62 63 64 65 |
# File 'lib/nested_multimap.rb', line 58 def [](*keys) i, l, r, k = 0, keys.length, self, self.class while r.is_a?(k) r = i < l ? r.hash_aref(keys[i]) : r.default i += 1 end r end |
#containers_with_default ⇒ Object
call-seq:
multimap.containers_with_default => array
Returns a new array populated with all the containers from map including the default.
map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map.containers_with_default #=> [[100, 101, 102], [100, 102], []]
141 142 143 144 145 |
# File 'lib/nested_multimap.rb', line 141 def containers_with_default containers = [] each_container_with_default { |container| containers << container } containers end |
#each_association ⇒ Object
call-seq:
multimap.each_association { |key, container| block } => multimap
Calls block once for each key/container in map, passing the key and container to the block as parameters.
map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map["c"] = 200
map.each_association { |key, container| puts "#{key} is #{container}" }
produces:
["a", "b"] is [100, 101, 102]
"c" is [200]
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/nested_multimap.rb', line 84 def each_association super do |key, container| if container.respond_to?(:each_association) container.each_association do |nested_key, value| yield [key, nested_key].flatten, value end else yield key, container end end end |
#each_container_with_default ⇒ Object
call-seq:
multimap.each_container_with_default { |container| block } => map
Calls block for every container in map including the default, passing the container as a parameter.
map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map.each_container_with_default { |container| puts container }
produces:
[100, 101, 102]
[100, 102]
[]
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/nested_multimap.rb', line 113 def each_container_with_default each_container = Proc.new do |container| if container.respond_to?(:each_container_with_default) container.each_container_with_default do |value| yield value end else yield container end end hash_each_pair { |_, container| each_container.call(container) } each_container.call(default) self end |
#height ⇒ Object
call-seq:
multimap.height => fixnum
Returns the deepest level of nesting.
map = NestedMultimap["a" => 100, "b" => 200]
map["a", "b"] = 101
map.height #=> 2
map["a", "b", "c"] = 102
map.height #=> 3
157 158 159 |
# File 'lib/nested_multimap.rb', line 157 def height containers_with_default.max { |a, b| a.length <=> b.length }.length end |
#inspect ⇒ Object
:nodoc:
161 162 163 |
# File 'lib/nested_multimap.rb', line 161 def inspect #:nodoc: super.gsub(/\}$/, ", default => #{default.inspect}}") end |
#store(*args) ⇒ Object Also known as: []=
call-seq:
multimap[*keys] = value => value
multimap.store(*keys, value) => value
Associates the value given by value with multiple key given by keys.
map = NestedMultimap.new
map["a"] = 100
map["a", "b"] = 101
map["a"] = 102
map #=> {"a"=>{"b"=>[100, 101, 102], default => [100, 102]}}
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/nested_multimap.rb', line 18 def store(*args) value = args.pop key = args.shift keys = args raise ArgumentError, 'wrong number of arguments (1 for 2)' unless value if keys.length > 0 update_container(key) do |container| container = self.class.new(container) unless container.is_a?(self.class) container[*keys] = value container end else super(key, value) end end |