Class: Xqsr3::Containers::MultiMap
- Inherits:
-
Hash
- Object
- Hash
- Xqsr3::Containers::MultiMap
show all
- Includes:
- Enumerable
- Defined in:
- lib/xqsr3/containers/multi_map.rb
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Enumerable
#collect_with_index, #detect_map, #unique
Methods inherited from Hash
#has_match?, #match
#deep_transform, #deep_transform!
Constructor Details
Returns a new instance of MultiMap.
131
132
133
134
|
# File 'lib/xqsr3/containers/multi_map.rb', line 131
def initialize
@inner = Hash.new
end
|
Class Method Details
.[](*args) ⇒ Object
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
# File 'lib/xqsr3/containers/multi_map.rb', line 60
def self.[] *args
return self.new if 0 == args.length
if 1 == args.length
arg = args[0]
case arg
when ::NilClass
return self.new
when ::Hash
fm = self.new
arg.each do |k, v|
raise ArgumentError, "mapped elements in hashes must be arrays, #{v.class} given" unless v.kind_of? ::Array
fm.store k, *v
end
return fm
when ::Array
return self.new if arg.empty?
if arg.all? { |el| ::Array === el }
h = Hash.new { |hash, key| hash[key] = [] }
arg.each do |ar|
raise ArgumentError, "cannot pass an empty array in array of arrays initialiser" if ar.empty?
key = ar.shift
ar.each { |value| h[key] << value }
end
return self.[](h)
end
raise ArgumentError, "array parameter not in an accepted form for subscript initialisation"
else
return self.[] arg.to_hash if arg.respond_to? :to_hash
raise TypeError, "given argument is neither a #{::Hash} nor an #{::Array} and does not respond to the to_hash method"
end
else
return self.[] [ *args ]
end
end
|
Instance Method Details
#==(rhs) ⇒ Object
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# File 'lib/xqsr3/containers/multi_map.rb', line 150
def == rhs
case rhs
when ::NilClass
return false
when ::Hash
return rhs.size == @inner.size && rhs == @inner
when self.class
return rhs.size == self.size && rhs == @inner
else
raise TypeError, "can compare #{self.class} only to instances of #{self.class} and #{::Hash}, but #{rhs.class} given"
end
false
end
|
#[](key) ⇒ Object
136
137
138
139
|
# File 'lib/xqsr3/containers/multi_map.rb', line 136
def [] key
return @inner[key]
end
|
#[]=(key, values) ⇒ Object
141
142
143
144
145
146
147
148
|
# File 'lib/xqsr3/containers/multi_map.rb', line 141
def []= key, values
values = [] if values.nil?
raise TypeError, "values must be an array, but #{values.class} given" unless values.kind_of? ::Array
store key, *values
end
|
#assoc(key) ⇒ Object
166
167
168
169
|
# File 'lib/xqsr3/containers/multi_map.rb', line 166
def assoc key
@inner.assoc key
end
|
#clear ⇒ Object
171
172
173
174
|
# File 'lib/xqsr3/containers/multi_map.rb', line 171
def clear
@inner.clear
end
|
#count ⇒ Object
176
177
178
179
|
# File 'lib/xqsr3/containers/multi_map.rb', line 176
def count
@inner.each_value.map { |ar| ar.size}.inject(0, :+)
end
|
#delete(key) ⇒ Object
181
182
183
184
|
# File 'lib/xqsr3/containers/multi_map.rb', line 181
def delete key
@inner.delete key
end
|
#each(*defaults) ⇒ Object
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/xqsr3/containers/multi_map.rb', line 186
def each *defaults
raise ArgumentError, "may only supply 0 or 1 defaults" if defaults.size > 1
@inner.each do |key, values|
if values.empty? && !defaults.empty?
yield key, defaults[0]
next
end
values.each { |value| yield key, value }
end
end
|
#each_key ⇒ Object
203
204
205
206
|
# File 'lib/xqsr3/containers/multi_map.rb', line 203
def each_key
@inner.each_key { |key| yield key }
end
|
#each_unflattened ⇒ Object
208
209
210
211
|
# File 'lib/xqsr3/containers/multi_map.rb', line 208
def each_unflattened
@inner.each { |key, value| yield key, value }
end
|
#each_unflattened_with_index ⇒ Object
213
214
215
216
|
# File 'lib/xqsr3/containers/multi_map.rb', line 213
def each_unflattened_with_index
@inner.each_with_index { |kv, index| yield kv, index }
end
|
#each_value ⇒ Object
218
219
220
221
222
223
224
|
# File 'lib/xqsr3/containers/multi_map.rb', line 218
def each_value
@inner.each do |key, values|
values.each { |value| yield value }
end
end
|
#each_with_index ⇒ Object
226
227
228
229
230
231
232
233
234
235
|
# File 'lib/xqsr3/containers/multi_map.rb', line 226
def each_with_index
index = 0
self.each do |key, value|
yield key, value, index
index += 1
end
end
|
#empty? ⇒ Boolean
237
238
239
240
|
# File 'lib/xqsr3/containers/multi_map.rb', line 237
def empty?
@inner.empty?
end
|
#eql?(rhs) ⇒ Boolean
242
243
244
245
246
247
248
249
250
|
# File 'lib/xqsr3/containers/multi_map.rb', line 242
def eql? rhs
case rhs
when self.class
return self == rhs
else
return false
end
end
|
#fetch(key, default = nil, &block) ⇒ Object
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
# File 'lib/xqsr3/containers/multi_map.rb', line 252
def fetch key, default = nil, &block
case default
when ::NilClass, ::Array
;
else
raise TypeError, "default parameter ('#{default}') must be of type #{::Array}, but was of type #{default.class}"
end
unless @inner.has_key? key
return default unless default.nil?
if block_given?
r = nil
case block.arity
when 0
r = yield
when 1
r = yield key
else
raise ArgumentError, "given block must take a single parameter - #{block.arity} given"
end
case r
when ::Array
;
else
raise ArgumentError, "given block must return a value of type #{::Array} or one convertible implicitly to such" unless r.respond_to? :to_ary
r = r.to_ary
end
return r
end
raise KeyError, "given key '#{key}' (#{key.class}) does not exist"
end
@inner.fetch key
end
|
#flatten ⇒ Object
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
# File 'lib/xqsr3/containers/multi_map.rb', line 296
def flatten
r = []
@inner.each do |key, values|
if values.empty?
r << key << []
else
values.each do |value|
r << key << value
end
end
end
r
end
|
#has_key?(key) ⇒ Boolean
317
318
319
320
|
# File 'lib/xqsr3/containers/multi_map.rb', line 317
def has_key? key
@inner.has_key? key
end
|
#has_value?(value) ⇒ Boolean
322
323
324
325
|
# File 'lib/xqsr3/containers/multi_map.rb', line 322
def has_value? value
@inner.has_value? value
end
|
#key(value) ⇒ Object
327
328
329
330
|
# File 'lib/xqsr3/containers/multi_map.rb', line 327
def key value
@inner.key value
end
|
#merge(fm) ⇒ Object
332
333
334
335
336
337
338
339
340
341
342
|
# File 'lib/xqsr3/containers/multi_map.rb', line 332
def merge fm
raise TypeError, "parameter must be an instance of type #{self.class}" unless fm.instance_of? self.class
fm_new = self.class.new
fm_new.merge! self
fm_new.merge! fm
fm_new
end
|
#merge!(fm) ⇒ Object
344
345
346
347
348
349
350
351
352
|
# File 'lib/xqsr3/containers/multi_map.rb', line 344
def merge! fm
fm.each do |k, v|
self.push k, v
end
self
end
|
#push(key, *values) ⇒ Object
354
355
356
357
358
359
|
# File 'lib/xqsr3/containers/multi_map.rb', line 354
def push key, *values
@inner[key] = [] unless @inner.has_key? key
@inner[key].push(*values)
end
|
#shift ⇒ Object
361
362
363
364
|
# File 'lib/xqsr3/containers/multi_map.rb', line 361
def shift
@inner.shift
end
|
#size ⇒ Object
366
367
368
369
|
# File 'lib/xqsr3/containers/multi_map.rb', line 366
def size
@inner.size
end
|
#store(key, *values) ⇒ Object
371
372
373
374
|
# File 'lib/xqsr3/containers/multi_map.rb', line 371
def store key, *values
@inner[key] = values
end
|
#to_a ⇒ Object
376
377
378
379
|
# File 'lib/xqsr3/containers/multi_map.rb', line 376
def to_a
self.flatten
end
|
#to_h ⇒ Object
381
382
383
384
|
# File 'lib/xqsr3/containers/multi_map.rb', line 381
def to_h
@inner.dup
end
|
#values ⇒ Object
386
387
388
389
|
# File 'lib/xqsr3/containers/multi_map.rb', line 386
def values
@inner.values
end
|