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, #unique
Constructor Details
Returns a new instance of MultiMap.
128
129
130
131
|
# File 'lib/xqsr3/containers/multi_map.rb', line 128
def initialize
@inner = Hash.new
end
|
Class Method Details
.[](*args) ⇒ Object
57
58
59
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
|
# File 'lib/xqsr3/containers/multi_map.rb', line 57
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/xqsr3/containers/multi_map.rb', line 147
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
133
134
135
136
|
# File 'lib/xqsr3/containers/multi_map.rb', line 133
def [] key
return @inner[key]
end
|
#[]=(key, values) ⇒ Object
138
139
140
141
142
143
144
145
|
# File 'lib/xqsr3/containers/multi_map.rb', line 138
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
163
164
165
166
|
# File 'lib/xqsr3/containers/multi_map.rb', line 163
def assoc key
@inner.assoc key
end
|
#clear ⇒ Object
168
169
170
171
|
# File 'lib/xqsr3/containers/multi_map.rb', line 168
def clear
@inner.clear
end
|
#count ⇒ Object
173
174
175
176
|
# File 'lib/xqsr3/containers/multi_map.rb', line 173
def count
@inner.each_value.map { |ar| ar.size}.inject(0, :+)
end
|
#delete(key) ⇒ Object
178
179
180
181
|
# File 'lib/xqsr3/containers/multi_map.rb', line 178
def delete key
@inner.delete key
end
|
#each(*defaults) ⇒ Object
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
# File 'lib/xqsr3/containers/multi_map.rb', line 183
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
200
201
202
203
|
# File 'lib/xqsr3/containers/multi_map.rb', line 200
def each_key
@inner.each_key { |key| yield key }
end
|
#each_unflattened ⇒ Object
205
206
207
208
|
# File 'lib/xqsr3/containers/multi_map.rb', line 205
def each_unflattened
@inner.each { |key, value| yield key, value }
end
|
#each_unflattened_with_index ⇒ Object
210
211
212
213
|
# File 'lib/xqsr3/containers/multi_map.rb', line 210
def each_unflattened_with_index
@inner.each_with_index { |kv, index| yield kv, index }
end
|
#each_value ⇒ Object
215
216
217
218
219
220
221
|
# File 'lib/xqsr3/containers/multi_map.rb', line 215
def each_value
@inner.each do |key, values|
values.each { |value| yield value }
end
end
|
#each_with_index ⇒ Object
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/xqsr3/containers/multi_map.rb', line 223
def each_with_index
index = 0
self.each do |key, value|
yield key, value, index
index += 1
end
end
|
#empty? ⇒ Boolean
234
235
236
237
|
# File 'lib/xqsr3/containers/multi_map.rb', line 234
def empty?
@inner.empty?
end
|
#eql?(rhs) ⇒ Boolean
239
240
241
242
243
244
245
246
247
|
# File 'lib/xqsr3/containers/multi_map.rb', line 239
def eql? rhs
case rhs
when self.class
return self == rhs
else
return false
end
end
|
#fetch(key, default = nil, &block) ⇒ Object
249
250
251
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
|
# File 'lib/xqsr3/containers/multi_map.rb', line 249
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
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
|
# File 'lib/xqsr3/containers/multi_map.rb', line 293
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
314
315
316
317
|
# File 'lib/xqsr3/containers/multi_map.rb', line 314
def has_key? key
@inner.has_key? key
end
|
#has_value?(value) ⇒ Boolean
319
320
321
322
|
# File 'lib/xqsr3/containers/multi_map.rb', line 319
def has_value? value
@inner.has_value? value
end
|
#key(value) ⇒ Object
324
325
326
327
|
# File 'lib/xqsr3/containers/multi_map.rb', line 324
def key value
@inner.key value
end
|
#merge(fm) ⇒ Object
329
330
331
332
333
334
335
336
337
338
339
|
# File 'lib/xqsr3/containers/multi_map.rb', line 329
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
341
342
343
344
345
346
347
348
349
|
# File 'lib/xqsr3/containers/multi_map.rb', line 341
def merge! fm
fm.each do |k, v|
self.push k, v
end
self
end
|
#push(key, *values) ⇒ Object
351
352
353
354
355
356
|
# File 'lib/xqsr3/containers/multi_map.rb', line 351
def push key, *values
@inner[key] = [] unless @inner.has_key? key
@inner[key].push(*values)
end
|
#shift ⇒ Object
358
359
360
361
|
# File 'lib/xqsr3/containers/multi_map.rb', line 358
def shift
@inner.shift
end
|
#size ⇒ Object
363
364
365
366
|
# File 'lib/xqsr3/containers/multi_map.rb', line 363
def size
@inner.size
end
|
#store(key, *values) ⇒ Object
368
369
370
371
|
# File 'lib/xqsr3/containers/multi_map.rb', line 368
def store key, *values
@inner[key] = values
end
|
#to_a ⇒ Object
373
374
375
376
|
# File 'lib/xqsr3/containers/multi_map.rb', line 373
def to_a
self.flatten
end
|
#to_h ⇒ Object
378
379
380
381
|
# File 'lib/xqsr3/containers/multi_map.rb', line 378
def to_h
@inner.dup
end
|
#values ⇒ Object
383
384
385
386
|
# File 'lib/xqsr3/containers/multi_map.rb', line 383
def values
@inner.values
end
|