Class: Multimap

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/multimap.rb

Overview

概要(Basic information)

Rubyによる多重連想配列(マルチマップ)の実装です。通常の連想配列(Rubyでは“Hash”クラス)と異なり、多重連想配列は1つのキーに対して複数の要素が存在し得ます。

メソッド名は基本的にHashクラスに合わせてあります。またHashクラスが持つメソッドの大部分を実装していますが、いくつか未実装なものもあります。

Ruby implementation of multimap. Unlike ordinary map, also known as associative array (see Ruby documentation for “Hash” class), multimap can contain two or more items for a key.

Most methods’ names are same as those of Hash class, and all other than a few methods in Hash class is implemented on Multimap class.

Instance Method Summary collapse

Constructor Details

#initializeMultimap

新しい多重連想配列を生成します。Hash#newと異なり、デフォルト値は設定できません。

Generates a new multimap. Different from Hash#new , you can not specify default value.



35
36
37
# File 'lib/multimap.rb', line 35

def initialize
  @assoc = Hash.new{ |hash, key| hash[key] = Multiset.new }
end

Instance Method Details

#==(other) ⇒ Object

selfotherと等しいかどうかを返します。

Returns whether self is equal to other.



84
85
86
87
# File 'lib/multimap.rb', line 84

def ==(other)
  return false unless other.instance_of?(Multimap)
  @assoc == other.to_hash
end

#clearObject

selfに格納された要素をすべて削除します。selfを返します。

Removes all elements stored in self. Returns self.



105
106
107
# File 'lib/multimap.rb', line 105

def clear
  @assoc.clear
end

#delete(key) ⇒ Object

keyに割り当てられた全ての値を削除し、その値をMultisetとして返します。

Deletes all values associated with key, and returns those values as a Multiset.



134
135
136
137
138
# File 'lib/multimap.rb', line 134

def delete(key)
  ret = @assoc[key]
  @assoc.delete(key)
  ret
end

#delete_if(&block) ⇒ Object

ブロックにselfのキーと値の組(値は1つ)を順次与え、結果が真であった組をすべて削除します。selfを返します。

Gives all pairs of a key and single value in self to given block, and deletes that element if the block returns true. Returns self.



160
161
162
163
164
165
166
167
168
# File 'lib/multimap.rb', line 160

def delete_if(&block) # :yields: key, single_value
  cleanup
  @assoc.each_pair do |key, value_list|
    value_list.delete_if{ |single_value|
      block.call(key, single_value)
    }
  end
  self
end

#delete_with(&block) ⇒ Object

delete_ifと同じですが、ブロックへの引数が(キー、キーに割り当てられた値、その値がキーに割り当てられている個数)の3つの組で与えられます。

Same as delete_if, but arguments given to block is the tuple of three: (key, one value associated with the key, numbers of that value associated with the key).



204
205
206
207
208
209
210
211
212
# File 'lib/multimap.rb', line 204

def delete_with(&block) # :yields: key, a_value, count
  cleanup
  @assoc.each_pair do |key, value_list|
    value_list.delete_with{ |a_value, count|
      block.call(key, a_value, count)
    }
  end
  self
end

#dupObject

selfの複製を生成して返します。

Returns duplicated self.



112
113
114
# File 'lib/multimap.rb', line 112

def dup
  @assoc.to_multimap
end

#each_key(&block) ⇒ Object

selfのすべてのキーについて繰り返します。selfを返します。

Iterates for each key in self. Returns self.



273
274
275
276
# File 'lib/multimap.rb', line 273

def each_key(&block) # :yields: key
  cleanup
  @assoc.each_key &block
end

#each_pairObject Also known as: each

selfのすべてのキーと値の組について繰り返します。selfを返します。

Iterates for each pair of a key and a value in self. Returns self.



219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/multimap.rb', line 219

def each_pair
  if block_given?
    cleanup
    @assoc.each_pair do |key, value_list|
      value_list.each do |single_value|
        yield key, single_value
      end
    end
    self
  else
    Enumerator.new(self, :each_pair)
  end
end

#each_pair_list(&block) ⇒ Object

selfのすべてのキーと、そのキーに割り当てられたすべての値(Multisetで与えられる)の組について繰り返します。selfを返します。

Iterates for each pair of a key and all values associated with the key (list of values is given as Multiset) in self. Returns self.



263
264
265
266
# File 'lib/multimap.rb', line 263

def each_pair_list(&block) # :yields: key, value_list
  cleanup
  @assoc.each_pair &block
end

#each_pair_withObject

selfのすべてのキーと値の組について、ブロックに(キー、キーに割り当てられた値、その値が割り当てられた数)の組を与えながら繰り返します。selfを返します。

Iterates for each pair of a key and a value in self, giving the tuple of three to block: (key, one value associated with the key, numbers of that value associated with the key). Returns self.



242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/multimap.rb', line 242

def each_pair_with
  if block_given?
    cleanup
    @assoc.each_pair do |key, value_list|
      value_list.each_pair do |a_value, count|
        yield key, a_value, count
      end
    end
    self
  else
    Enumerator.new(self, :each_pair_with)
  end
end

#each_value(&block) ⇒ Object

selfのすべての値について繰り返します。selfを返します。

Iterates for each value in self. Returns self.



282
283
284
285
286
287
288
289
290
291
292
# File 'lib/multimap.rb', line 282

def each_value(&block) # :yields: single_value
  if block_given?
    cleanup
    @assoc.each_value do |value_list|
      value_list.each &block
    end
    self
  else
    Enumerator.new(self, :each_value)
  end
end

#empty?Boolean

selfに要素がないかどうかを返します。

Returns whether self has no element.

Returns:

  • (Boolean)


318
319
320
321
# File 'lib/multimap.rb', line 318

def empty?
  cleanup
  @assoc.empty?
end

#fetch(key) ⇒ Object Also known as: []

キーkeyに対応する値(複数存在しうる)を、Multisetとして返します。Hash#fetchの場合と異なり、キーに対応する値が存在しない場合の扱いを指定することはできません。(そのような場合、空のMultisetが返ります。)

Returns values associated with key with format of Multiset. Different from Hash#fetch, you can not specify a value or a process when key has not associated with any value. If key has not associated with any value, Multimap#fetch returns empty Multiset.



56
57
58
# File 'lib/multimap.rb', line 56

def fetch(key)
  @assoc[key]
end

#has_key?(key) ⇒ Boolean Also known as: key?, include?, member?

selfにキーkeyかあるかどうかを返します。

Returns whether self has a key key.

Returns:

  • (Boolean)


326
327
328
329
# File 'lib/multimap.rb', line 326

def has_key?(key)
  cleanup
  @assoc.has_key?(key)
end

#has_value?(value) ⇒ Boolean Also known as: value?

selfに値valueかあるかどうかを返します。

Returns whether self has a value value.

Returns:

  • (Boolean)


337
338
339
# File 'lib/multimap.rb', line 337

def has_value?(value)
  self.values.items.include?(value)
end

#inspectObject

:nodoc:



447
448
449
450
451
452
# File 'lib/multimap.rb', line 447

def inspect # :nodoc:
  buf = "#<Multimap:"
  buf += self.to_s(', ')
  buf += '>'
  buf
end

#invertObject

selfのキーと値を入れ替えたMultimapを返します。例えばキー:aに対応する値が2つの:xと1つの:yであれば、変換結果はキー:xに:aが2つ、キー:yに:aが1つ対応するMultimapです。

Returns a Multimap whose keys are values in self, and values are keys in self. For example, If self has a key :a associated with two :x and one :y, returned multimap has two keys :x and :y, and their values are two :a and one :a respectively.



381
382
383
384
385
386
387
# File 'lib/multimap.rb', line 381

def invert
  ret = Multimap.new
  self.each_pair_with do |key, a_value, count|
    ret[a_value].add key, count
  end
  ret
end

#key(value) ⇒ Object Also known as: index

selfから値がvalueであるような要素を検索し、それに対応するキーを返します。該当するキーが複数存在する場合、そのうちの1つを返します。該当するキーが存在しなければnilを返します。

Search a pair of key and value from self such that the value is equal to the argument value. If two or keys are matched, returns one of them. If no key is matched, returns nil.



351
352
353
354
355
356
# File 'lib/multimap.rb', line 351

def key(value)
  self.each_pair_with do |key, a_value, count|
    return key if value == a_value
  end
  nil
end

#keysObject

selfのすべてのキーを、配列として返します。

Returns an array in which keys in self are stored.



297
298
299
300
# File 'lib/multimap.rb', line 297

def keys
  cleanup
  @assoc.keys
end

#merge(other) ⇒ Object Also known as: +

selfotherの要素を合わせた多重集合を返します。

Returns merged multiset of self and other.



414
415
416
417
# File 'lib/multimap.rb', line 414

def merge(other)
  ret = self.dup
  ret.merge! other
end

#merge!(other) ⇒ Object

selfotherの要素を追加します。selfを返します。

Add elements in other to self. Returns self.



404
405
406
407
408
409
# File 'lib/multimap.rb', line 404

def merge!(other)
  other.each_pair_with do |key, a_value, count|
    self[key].add a_value, count
  end
  self
end

#reject(&block) ⇒ Object

delete_ifと同じですが、self自身からはキーと値の組を削除せず、要素が削除された結果の多重連想配列を新たに生成して返します。

Same as delete_if, but generates a new Multimap whose pairs of key and value are deleted, instead of deleting pairs in self.



147
148
149
150
151
# File 'lib/multimap.rb', line 147

def reject(&block) # :yields: key, single_value
  ret = self.dup
  ret.delete_if &block
  ret
end

#reject!(&block) ⇒ Object

delete_ifと同じですが、キーと値の組が1つも削除されなければnilを返します。

Same as delete_if, but returns nil if no pair of key and value is deleted.



175
176
177
178
179
180
181
182
183
184
# File 'lib/multimap.rb', line 175

def reject!(&block) # :yields: key, single_value
  cleanup
  ret = nil
  @assoc.each_pair do |key, value_list|
    ret = self if value_list.reject!{ |single_value|
      block.call(key, single_value)
    }
  end
  ret
end

#reject_with(&block) ⇒ Object

rejectと同じですが、ブロックへの引数が(キー、キーに割り当てられた値、その値がキーに割り当てられている個数)の3つの組で与えられます。

Same as reject, but arguments given to block is the tuple of three: (key, one value associated with the key, numbers of that value associated with the key).



192
193
194
195
196
# File 'lib/multimap.rb', line 192

def reject_with(&block) # :yields: key, a_value, count
  ret = self.dup
  ret.delete_with &block
  ret
end

#replace(other) ⇒ Object

selfの内容をotherのものに置き換えます。selfを返します。

Replaces self by other. Returns self.



121
122
123
124
125
126
127
# File 'lib/multimap.rb', line 121

def replace(other)
  @assoc.clear
  other.each_pair_with do |key, a_value, count|
    @assoc[key].add a_value, count
  end
  self
end

#sizeObject Also known as: length

selfに含まれている要素数を返します。

Returns number of all elements in self.



392
393
394
395
396
# File 'lib/multimap.rb', line 392

def size
  ret = 0
  self.each_pair_with{ |key, a_value, count| ret += count }
  ret
end

#store(key, value_list) ⇒ Object Also known as: []=

キーkeyに対応する値(複数存在しうる)をvalue_listで置き換えます。この際、value_listはMultiset.parseを用いてMultisetに変換されます。

value_listを返します。

Sets values associated with key to value_list. value_list is converted to a Multiset by Multiset.parse .

Returns value_list.



71
72
73
74
75
76
77
78
# File 'lib/multimap.rb', line 71

def store(key, value_list)
  if value_list.class == Multiset
    @assoc[key] = value_list.dup
  else
    @assoc[key] = Multiset.parse(value_list)
  end
  value_list
end

#to_hashObject

selfHashに変換して返します。生成されるハッシュの構造については、Hash#to_multimapをご覧下さい。その際、返されるハッシュにおいて値はすべてMultimap型となります。

Converts self to a Hash. See Hash#to_multimap about format of generated hash. All values in the returned hash are multimaps.



96
97
98
# File 'lib/multimap.rb', line 96

def to_hash
  @assoc.dup
end

#to_s(delim = "\n") ⇒ Object

:nodoc:



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/multimap.rb', line 420

def to_s(delim = "\n") # :nodoc:
  cleanup
  
  buf = ''
  init = true
  @assoc.each_pair do |key, value_list|
    if init
      init = false
    else
      buf += delim
    end
    buf += "#{key.inspect}=>{"
    
    init_val = true
    value_list.each_pair do |a_value, count|
      if init_val
        init_val = false
      else
        buf += ", "
      end
      buf += "\##{count} #{a_value.inspect}"
    end
    buf += "}"
  end
  buf
end

#valuesObject

selfのすべての値を、Multisetとして返します。

Returns a Multiset in which values in self are stored.



306
307
308
309
310
311
312
313
# File 'lib/multimap.rb', line 306

def values
  cleanup
  ret = Multiset.new
  @assoc.each_value do |value_list|
    ret.merge! value_list
  end
  ret
end

#values_at(*key_list) ⇒ Object Also known as: indexes, indices

selfからkey_listの各キーに対応する値(Multiset型)を取り出し、それらを配列として返します。すなわち、Multisetを要素とする配列を返します。

Gets values (instances of Multiset) of self associated with key_list, and returns those values as an array. i.e. returns an array whose elements are multisets.



366
367
368
# File 'lib/multimap.rb', line 366

def values_at(*key_list)
  key_list.map{ |key| self[key] }
end