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
207
208
|
# File 'lib/xqsr3/containers/multi_map.rb', line 203
def each_key
return @inner.each_key unless block_given?
@inner.each_key { |key| yield key }
end
|
#each_unflattened ⇒ Object
210
211
212
213
|
# File 'lib/xqsr3/containers/multi_map.rb', line 210
def each_unflattened
@inner.each { |key, value| yield key, value }
end
|
#each_unflattened_with_index ⇒ Object
215
216
217
218
|
# File 'lib/xqsr3/containers/multi_map.rb', line 215
def each_unflattened_with_index
@inner.each_with_index { |kv, index| yield kv, index }
end
|
#each_value ⇒ Object
220
221
222
223
224
225
226
|
# File 'lib/xqsr3/containers/multi_map.rb', line 220
def each_value
@inner.each do |key, values|
values.each { |value| yield value }
end
end
|
#each_with_index ⇒ Object
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/xqsr3/containers/multi_map.rb', line 228
def each_with_index
index = 0
self.each do |key, value|
yield key, value, index
index += 1
end
end
|
#empty? ⇒ Boolean
239
240
241
242
|
# File 'lib/xqsr3/containers/multi_map.rb', line 239
def empty?
@inner.empty?
end
|
#eql?(rhs) ⇒ Boolean
244
245
246
247
248
249
250
251
252
|
# File 'lib/xqsr3/containers/multi_map.rb', line 244
def eql? rhs
case rhs
when self.class
return self == rhs
else
return false
end
end
|
#fetch(key, default = nil, &block) ⇒ Object
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
295
296
|
# File 'lib/xqsr3/containers/multi_map.rb', line 254
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
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
# File 'lib/xqsr3/containers/multi_map.rb', line 298
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
319
320
321
322
|
# File 'lib/xqsr3/containers/multi_map.rb', line 319
def has_key? key
@inner.has_key? key
end
|
#has_value?(value) ⇒ Boolean
324
325
326
327
|
# File 'lib/xqsr3/containers/multi_map.rb', line 324
def has_value? value
@inner.has_value? value
end
|
#key(value) ⇒ Object
329
330
331
332
|
# File 'lib/xqsr3/containers/multi_map.rb', line 329
def key value
@inner.key value
end
|
#merge(fm) ⇒ Object
334
335
336
337
338
339
340
341
342
343
344
|
# File 'lib/xqsr3/containers/multi_map.rb', line 334
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
346
347
348
349
350
351
352
353
354
|
# File 'lib/xqsr3/containers/multi_map.rb', line 346
def merge! fm
fm.each do |k, v|
self.push k, v
end
self
end
|
#push(key, *values) ⇒ Object
356
357
358
359
360
361
|
# File 'lib/xqsr3/containers/multi_map.rb', line 356
def push key, *values
@inner[key] = [] unless @inner.has_key? key
@inner[key].push(*values)
end
|
#shift ⇒ Object
363
364
365
366
|
# File 'lib/xqsr3/containers/multi_map.rb', line 363
def shift
@inner.shift
end
|
#size ⇒ Object
368
369
370
371
|
# File 'lib/xqsr3/containers/multi_map.rb', line 368
def size
@inner.size
end
|
#store(key, *values) ⇒ Object
373
374
375
376
|
# File 'lib/xqsr3/containers/multi_map.rb', line 373
def store key, *values
@inner[key] = values
end
|
#to_a ⇒ Object
378
379
380
381
|
# File 'lib/xqsr3/containers/multi_map.rb', line 378
def to_a
self.flatten
end
|
#to_h ⇒ Object
383
384
385
386
|
# File 'lib/xqsr3/containers/multi_map.rb', line 383
def to_h
@inner.dup
end
|
#values ⇒ Object
388
389
390
391
|
# File 'lib/xqsr3/containers/multi_map.rb', line 388
def values
@inner.values
end
|