Class: Multiset
Overview
概要(Basic information)
Rubyによる多重集合(マルチセット)の実装です。通常の集合(Rubyでは“set”ライブラリ)と異なり、多重集合は同一の要素を複数格納することができます。
メソッド名は基本的にSetクラスに合わせてあります。またSetクラスが持つメソッドの大部分を実装していますが、いくつか未実装なものもあります。
Ruby implementation of multiset. Unlike ordinary set(see Ruby documentation for “set” library), multiset can contain two or more same items.
Most methods’ names are same as those of Set class, and all other than a few methods in Set class is implemented on Multiset class.
-
Set[:a,:b,:c,:b,:b,:c] => #<Set: {:b, :c, :a}> -
Multiset[:a,:b,:c,:b,:b,:c] => #<Multiset:#3 :b, #2 :c, #1 :a>
Class Method Summary collapse
-
.[](*list) ⇒ Object
listに含まれる要素からなる多重集合を生成します。newを用いる場合と異なり、引数の1つ1つが多重集合の要素になります。. -
.from_lines(str) ⇒ Object
文字列を行単位で区切ってMultisetにします。.
-
.parse(object) ⇒ Object
objectを多重集合に変換し生成します。 *objectがMultisetのインスタンスである場合、 その複製を返します。 *objectがMultisetのインスタンスでなく、 かつeach_pairメソッドを持っている場合、each_pairから渡される2つの引数について、前者を要素、 後者をその個数とした多重集合を生成します。Hash#to_multisetも ご覧下さい。 *objectがeach_pairメソッドを持っておらず、 かつEnumerableである場合は、Multiset#newと同じ結果です。 * それ以外の場合は、例外ArgumentErrorが発生します。. -
.parse_force(object) ⇒ Object
文字列が渡された場合は、Multiset.from_linesと同じ挙動。 それ以外の場合は、Multiset.parseと同じ挙動。.
Instance Method Summary collapse
-
#&(other) ⇒ Object
selfとotherの積集合からなる多重集合を返します。. -
#==(other) ⇒ Object
selfがotherと等しいかどうかを返します。. -
#add(item, addcount = 1) ⇒ Object
(also: #<<)
selfに、addcount個のitemを追加します。 成功した場合はselfを、失敗した場合はnilを返します。. -
#clear ⇒ Object
selfの要素をすべて削除します。selfを返します。. -
#compare_set_with(other) ⇒ Object
selfとotherが持つすべての要素(重複なし)について 繰り返し、ブロックの返り値が偽であるものが存在すればその時点でfalseを返します。 すべての要素について真であればtrueを返します。. -
#count(*item_list) ⇒ Object
self中に含まれるitemの個数を返します。 引数を指定しない場合は、Multiset#sizeと同じです。 ブロックを指定することもでき、その場合は(重複しない)各要素をブロックに与え、 条件を満たした(結果が真であった)要素がMultiset内にいくつ入っているかを数えます。. -
#delete(item, delcount = 1) ⇒ Object
selfから、delcount個のitemを削除します。 成功した場合はselfを、失敗した場合はnilを返します。. -
#delete_all(item) ⇒ Object
selfに含まれるitemをすべて削除します。selfを返します。. -
#delete_if ⇒ Object
ブロックに
selfの要素(重複なし)を順次与え、 結果が真であった要素をすべて削除します。selfを返します。. -
#delete_with ⇒ Object
selfに含まれるすべての要素(重複なし)とその個数について、 その組をブロックに与え、結果が真であった要素をすべて削除します。selfを返します。. -
#dup ⇒ Object
selfの複製を生成して返します。. -
#each ⇒ Object
selfに含まれるすべての要素について繰り返します。selfを返します。 ブロックが与えられていない場合、Enumeratorを返します。. -
#each_item(&block) ⇒ Object
selfに含まれるすべての要素について、重複を許さずに繰り返します。selfを返します。 ブロックが与えられていない場合、Enumeratorを返します。. -
#each_with_count(&block) ⇒ Object
(also: #each_pair)
selfに含まれるすべての要素(重複なし)とその個数について繰り返します。selfを返します。 ブロックが与えられていない場合、Enumeratorを返します。. -
#empty? ⇒ Boolean
selfに要素がないかどうかを返します。. -
#eql?(other) ⇒ Boolean
:nodoc:.
-
#find(ifnone = nil, &block) ⇒ Object
(also: #detect)
ブロックに
selfの要素(重複なし)を順次与え、 最初に結果が真であった要素を返します。 見つからなかった場合は、ifnoneが指定されている場合は ifnone.call し、 そうでなければnilを返します。 ブロックを与えなかった場合、そのためのEnumeratorを返します。. -
#find_all(&block) ⇒ Object
(also: #select)
ブロックに
selfの要素(重複なし)を順次与え、 結果が真であった要素を集めた多重集合を返します。 ブロックを与えなかった場合、そのためのEnumeratorを返します。. -
#find_all_with(&block) ⇒ Object
(also: #select_with)
Multiset#find_allと同じですが、ブロックには
selfの要素とその個数の組が与えられます。. -
#find_all_with_(&block) ⇒ Object
:nodoc:.
-
#find_with(ifnone = nil, &block) ⇒ Object
(also: #detect_with)
Multiset#findと同じですが、ブロックには
selfの要素とその個数の組が与えられます。. -
#flatten ⇒ Object
self中に含まれる多重集合を平滑化したものを返します。. -
#flatten! ⇒ Object
self中に含まれる多重集合を平滑化します。 平滑化した多重集合が1つでもあればselfを、 そうでなければnilを返します。. -
#grep(pattern) ⇒ Object
patternの条件を満たした(pattern=== item)要素のみを集めた多重集合を返します。 ブロックが与えられている場合は、さらにその結果を適用した結果を返します。. -
#group_by ⇒ Object
(also: #classify)
selfの要素を、与えられたブロックからの返り値によって分類します。 ブロックからの返り値をキーとして値を対応付けたMultimapを返します。. -
#group_by_with ⇒ Object
(also: #classify_with)
Multiset#group_byと同様ですが、ブロックには要素とその個数の組が与えられます。.
-
#hash ⇒ Object
:nodoc:.
-
#include?(item) ⇒ Boolean
(also: #member?)
itemがself中に含まれているかを返します。. -
#initialize(list = nil) ⇒ Multiset
constructor
listに含まれる要素からなる多重集合を生成します。listを省略した場合、空の多重集合を生成します。. -
#inject_with(init) ⇒ Object
ブロックに「1回前のブロック呼び出しの返り値」「
selfの要素」「その個数」の 3つ組を順次与え、最後にブロックを呼んだ結果を返します。ただし「1回前のブロック呼び出しの返り値」は、 1回目のブロック呼び出しの際については、代わりにinitの値が与えられます。. -
#inspect ⇒ Object
:nodoc:.
-
#items ⇒ Object
selfに含まれている要素(重複は除く)からなる配列を返します。. -
#listing(delim = "\n") ⇒ Object
selfの全要素を(重複を許して)並べた文字列を返します。 要素間の区切りはdelimの値を用い、 各要素の表示形式は与えられたブロックの返り値(なければObject#inspect)を用います。. -
#map ⇒ Object
(also: #collect)
selfの各要素(重複なし)をブロックに与え、返り値を集めたものからなる 多重集合を生成します。. -
#map!(&block) ⇒ Object
(also: #collect!)
Multiset#mapと同様ですが、結果として生成される多重集合で
selfが 置き換えられます。selfを返します。. -
#map_with ⇒ Object
(also: #collect_with)
selfの要素(重複なし)とその個数の組をブロックに与えます。 ブロックから2要素の配列を受け取り、前者を要素、後者をその個数とした 多重集合を生成します。. -
#map_with! ⇒ Object
(also: #collect_with!)
Multiset#map_withと同様ですが、結果として生成される多重集合で
selfが置き換えられます。selfを返します。. -
#max(&block) ⇒ Object
最大の要素を返します。 要素が存在しない場合はnilを返します。 ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。.
-
#max_by(&block) ⇒ Object
ブロックの値を評価した結果が最大になるような要素を返します。 要素が存在しない場合はnilを返します。.
-
#max_by_with(&block) ⇒ Object
Multiset#max_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。.
-
#max_with ⇒ Object
Multiset#max と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の 4引数が与えられます。.
-
#merge(other) ⇒ Object
(also: #+)
selfとotherの要素を合わせた多重集合を返します。. -
#merge!(other) ⇒ Object
selfにotherの要素を追加します。selfを返します。. -
#min(&block) ⇒ Object
最小の要素を返します。 要素が存在しない場合はnilを返します。 ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。.
-
#min_by(&block) ⇒ Object
ブロックの値を評価した結果が最小になるような要素を返します。 要素が存在しない場合はnilを返します。.
-
#min_by_with(&block) ⇒ Object
Multiset#min_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。.
-
#min_with ⇒ Object
Multiset#min と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の 4引数が与えられます。.
-
#minmax(&block) ⇒ Object
最小の要素と最大の要素の組を返します。 ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。.
-
#minmax_by(&block) ⇒ Object
ブロックの値を評価した結果が最小になる要素と最大になる要素の組を返します。 要素が存在しない場合はnilを返します。.
-
#minmax_by_with(&block) ⇒ Object
Multiset#minmax_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。.
-
#minmax_with ⇒ Object
Multiset#minmax と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の 4引数が与えられます。.
-
#proper_subset?(other) ⇒ Boolean
selfがotherに真に含まれているかどうかを返します。 「真に」とは、両者が一致する場合は含めないことを示します。. -
#proper_superset?(other) ⇒ Boolean
selfがotherを真に含んでいるかどうかを返します。 「真に」とは、両者が一致する場合は含めないことを示します。. -
#reject ⇒ Object
ブロックに
selfの要素(重複なし)を順次与え、 結果が偽であった要素のみを集めたMultisetを返します。. -
#reject! ⇒ Object
Multiset#delete_ifと同じですが、要素が1つも削除されなければ
nilを返します。. -
#reject_with ⇒ Object
ブロックに
selfの要素(重複なし)と個数の組を順次与え、 結果が偽であった要素のみを集めたMultisetを返します。. -
#renew_count(item, number) ⇒ Object
selfに含まれるitemの個数をnumber個にします。numberが負の数であった場合は、number = 0とみなします。 成功した場合はselfを、失敗した場合はnilを返します。. -
#replace(other) ⇒ Object
selfの内容をotherのものに置き換えます。selfを返します。. -
#sample ⇒ Object
(also: #rand)
selfの要素を無作為に1つ選んで返します。 すべての要素は等確率で選ばれます。 空のmultisetに対して呼び出した場合はnilを返します。. -
#size ⇒ Object
(also: #length)
selfに含まれている要素数を返します。. -
#sort(&block) ⇒ Object
selfの要素を並び替えた配列を生成します。. -
#sort_by(&block) ⇒ Object
Multiset#sortと同様ですが、ブロックには1つの要素が与えられ、その値が小さいものから順に並びます。.
-
#sort_by_with ⇒ Object
Multiset#sort_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。.
-
#sort_with ⇒ Object
Multiset#sort と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の 4引数が与えられます。.
-
#subset?(other) ⇒ Boolean
selfがotherに含まれているかどうかを返します。. -
#subtract(other) ⇒ Object
(also: #-)
selfからotherの要素を取り除いた多重集合を返します。. -
#subtract!(other) ⇒ Object
selfからotherの要素を削除します。selfを返します。. -
#superset?(other) ⇒ Boolean
selfがotherを含んでいるかどうかを返します。. -
#to_a ⇒ Object
selfを配列に変換して返します。. -
#to_hash ⇒ Object
selfをHashに変換して返します。 生成されるハッシュの構造については、Hash#to_multisetをご覧下さい。. -
#to_s(delim = "\n") ⇒ Object
selfの要素と要素数の組を並べた文字列を返します。 要素間の区切りはdelimの値を用い、 各要素の表示形式は与えられたブロックの返り値(なければObject#inspect)を用います。. -
#to_set ⇒ Object
selfを通常の集合(Ruby標準添付のSet)に 変換したものを返します。. -
#|(other) ⇒ Object
selfとotherの和集合からなる多重集合を返します。.
Constructor Details
#initialize(list = nil) ⇒ Multiset
listに含まれる要素からなる多重集合を生成します。listを省略した場合、空の多重集合を生成します。
listにはEnumerableであるオブジェクトのみ指定できます。そうでない場合、例外ArgumentErrorが発生します。
Generates a multiset from items in list. If list is omitted, returns empty multiset.
list must be Enumerable. If not, ArgumentError is raised.
48 49 50 51 52 53 54 55 |
# File 'lib/multiset.rb', line 48 def initialize(list = nil) @entries = {} if list.kind_of?(Enumerable) list.each{ |item| add item } elsif list != nil raise ArgumentError, "Item list must include 'Enumerable' module" end end |
Class Method Details
.[](*list) ⇒ Object
listに含まれる要素からなる多重集合を生成します。newを用いる場合と異なり、引数の1つ1つが多重集合の要素になります。
主に多重集合のリテラルを生成するのに用います。
Generates a multiset from items in list. Unlike using new, each argument is one item in generated multiset.
This method is mainly used when you generate literal of multiset.
66 67 68 |
# File 'lib/multiset.rb', line 66 def Multiset.[](*list) Multiset.new(list) end |
.from_lines(str) ⇒ Object
文字列を行単位で区切ってMultisetにします。
Generates a Multiset from string, separated by lines.
117 118 119 |
# File 'lib/multiset.rb', line 117 def Multiset.from_lines(str) Multiset.new(str.enum_for(:each_line)) end |
.parse(object) ⇒ Object
objectを多重集合に変換し生成します。
-
objectがMultisetのインスタンスである場合、その複製を返します。 -
objectがMultisetのインスタンスでなく、かつeach_pairメソッドを持っている場合、each_pairから渡される2つの引数について、前者を要素、後者をその個数とした多重集合を生成します。Hash#to_multisetもご覧下さい。 -
objectがeach_pairメソッドを持っておらず、かつEnumerableである場合は、Multiset#newと同じ結果です。 -
それ以外の場合は、例外
ArgumentErrorが発生します。
Generates a multiset converting object.
-
If
objectis an instance of Multiset, returns duplicatedobject. -
If
objectis not an instance of Multiset and has the methodeach_pair, for each pair of two arguments fromeach_pair, first argument becomes item in multiset and second argument becomes its number. See also Hash#to_multiset . -
If
objectdoes not have the methodeach_pairandobjectincludesEnumerable, this method results equal to Multiset#new . -
Otherwise,
ArgumentErroris raised.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/multiset.rb', line 94 def Multiset.parse(object) if object.kind_of?(String) raise ArgumentError, "Multiset.parse can not parse strings. If you would like to store string lines to a multiset, use Multiset.from_lines(string)." end if object.instance_of?(Multiset) ret = object.dup else ret = Multiset.new if defined? object.each_pair object.each_pair{ |item, count| ret.add item, count } elsif object.kind_of?(Enumerable) object.each{ |item| ret.add item } else raise ArgumentError, "Source of Multiset must have 'each_pair' method or include 'Enumerable' module" end end ret end |
.parse_force(object) ⇒ Object
文字列が渡された場合は、Multiset.from_linesと同じ挙動。それ以外の場合は、Multiset.parseと同じ挙動。
If a string is given, it works as Multiset.from_lines, otherwise as Multiset.parse.
126 127 128 129 130 131 132 |
# File 'lib/multiset.rb', line 126 def Multiset.parse_force(object) if object.kind_of?(String) Multiset.from_lines(object) else Multiset.parse(object) end end |
Instance Method Details
#&(other) ⇒ Object
selfとotherの積集合からなる多重集合を返します。
Returns intersection of self and other.
542 543 544 545 546 547 548 |
# File 'lib/multiset.rb', line 542 def &(other) ret = Multiset.new (self.items & other.items).each do |item| ret.renew_count(item, [self.count(item), other.count(item)].min) end ret end |
#==(other) ⇒ Object
selfがotherと等しいかどうかを返します。
Returns whether self is equal to other.
480 481 482 483 |
# File 'lib/multiset.rb', line 480 def ==(other) return false unless other.instance_of?(Multiset) compare_set_with(other){ |s, o| s == o } end |
#add(item, addcount = 1) ⇒ Object Also known as: <<
selfに、addcount個のitemを追加します。成功した場合はselfを、失敗した場合はnilを返します。
Adds addcount number of items to self. Returns self if succeeded, or nil if failed.
379 380 381 382 383 384 |
# File 'lib/multiset.rb', line 379 def add(item, addcount = 1) return nil if addcount == nil a = addcount.to_i return nil if a <= 0 self.renew_count(item, self.count(item) + a) end |
#clear ⇒ Object
selfの要素をすべて削除します。selfを返します。
Deletes all items in self. Returns self.
248 249 250 251 |
# File 'lib/multiset.rb', line 248 def clear @entries.clear self end |
#compare_set_with(other) ⇒ Object
selfとotherが持つすべての要素(重複なし)について繰り返し、ブロックの返り値が偽であるものが存在すればその時点でfalseを返します。すべての要素について真であればtrueを返します。
このメソッドはsuperset?、subset?、== のために定義されています。
Iterates for each item in self and other, without duplication. If the given block returns false, then iteration immediately ends and returns false. Returns true if the given block returns true for all of iteration.
This method is defined for methods superset?, subset?, ==.
428 429 430 431 432 433 |
# File 'lib/multiset.rb', line 428 def compare_set_with(other) # :nodoc: :yields: number_in_self, number_in_other (self.items | other.items).each do |item| return false unless yield(self.count(item), other.count(item)) end true end |
#count(*item_list) ⇒ Object
self中に含まれるitemの個数を返します。引数を指定しない場合は、Multiset#sizeと同じです。ブロックを指定することもでき、その場合は(重複しない)各要素をブロックに与え、条件を満たした(結果が真であった)要素がMultiset内にいくつ入っているかを数えます。
Returns number of items in self. If the item is omitted, the value is same as Multiset#size. If a block is given, each element (without duplication) is given to the block, and returns the number of elements (including duplication) that returns true in the block.
:call-seq:
count(item)
count{ |item| ... }
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/multiset.rb', line 333 def count(*item_list) if block_given? unless item_list.empty? raise ArgumentError, "Both item and block cannot be given" end result = 0 @entries.each_pair do |i, c| result += c if yield(i) end result else case item_list.size when 0 self.size when 1 @entries.has_key?(item_list.first) ? @entries[item_list.first] : 0 else raise ArgumentError, "Only one item can be given" end end end |
#delete(item, delcount = 1) ⇒ Object
selfから、delcount個のitemを削除します。成功した場合はselfを、失敗した場合はnilを返します。
Deletes delcount number of items from self. Returns self if succeeded, nil otherwise.
393 394 395 396 397 398 |
# File 'lib/multiset.rb', line 393 def delete(item, delcount = 1) return nil if delcount == nil || !self.include?(item) d = delcount.to_i return nil if d <= 0 self.renew_count(item, self.count(item) - d) end |
#delete_all(item) ⇒ Object
selfに含まれるitemをすべて削除します。selfを返します。
Deletes all items in self. Returns self.
405 406 407 408 |
# File 'lib/multiset.rb', line 405 def delete_all(item) @entries.delete(item) self end |
#delete_if ⇒ Object
ブロックにselfの要素(重複なし)を順次与え、結果が真であった要素をすべて削除します。selfを返します。
Gives all items in self (without duplication) to given block, and deletes that item if the block returns true. Returns self.
785 786 787 788 789 790 |
# File 'lib/multiset.rb', line 785 def delete_if @entries.each_pair do |item, count| self.delete_all(item) if yield(item) end self end |
#delete_with ⇒ Object
selfに含まれるすべての要素(重複なし)とその個数について、その組をブロックに与え、結果が真であった要素をすべて削除します。selfを返します。
Gives each pair of (non-duplicate) item and its number to given block, and deletes those items if the block returns true. Returns self.
799 800 801 802 803 804 |
# File 'lib/multiset.rb', line 799 def delete_with @entries.each_pair do |item, count| @entries.delete(item) if yield(item, count) end self end |
#dup ⇒ Object
selfの複製を生成して返します。
Returns duplicated self.
137 138 139 |
# File 'lib/multiset.rb', line 137 def dup @entries.to_multiset end |
#each ⇒ Object
selfに含まれるすべての要素について繰り返します。selfを返します。ブロックが与えられていない場合、Enumeratorを返します。
このメソッドは Enumerable#each の挙動に合わせ、同じ要素を何度もブロックに渡すため、効率が悪いです。Multiset#each_item, Multiset#each_pairの利用もご検討下さい。例えば「“a”が100個入ったMultiset」をeachで繰り返すと100回の処理が行われますが、each_pairなら1回で済みます。
Iterates for each item in self. Returns self. An Enumerator will be returned if no block is given.
This method is ineffective since the same element in the Multiset can be given to the block for many times, same as the behavior of Enumerable#each. Please consider using Multiset#each_item or Multiset#each_pair: for example, a Multiset with 100 times “a” will call the given block for 100 times for Multiset#each, while only once for Multiset#each_pair.
585 586 587 588 589 590 591 592 593 594 |
# File 'lib/multiset.rb', line 585 def each if block_given? @entries.each_pair do |item, count| count.times{ yield item } end self else Enumerator.new(self, :each) end end |
#each_item(&block) ⇒ Object
selfに含まれるすべての要素について、重複を許さずに繰り返します。selfを返します。ブロックが与えられていない場合、Enumeratorを返します。
Iterates for each item in self, without duplication. Returns self. An Enumerator will be returned if no block is given.
603 604 605 606 607 608 609 610 |
# File 'lib/multiset.rb', line 603 def each_item(&block) # :yields: item if block @entries.each_key(&block) self else @entries.each_key end end |
#each_with_count(&block) ⇒ Object Also known as: each_pair
selfに含まれるすべての要素(重複なし)とその個数について繰り返します。selfを返します。ブロックが与えられていない場合、Enumeratorを返します。
Iterates for each pair of (non-duplicated) item and its number in self. Returns self. An Enumerator will be returned if no block is given.
619 620 621 622 623 624 625 626 |
# File 'lib/multiset.rb', line 619 def each_with_count(&block) # :yields: item, count if block @entries.each_pair(&block) self else @entries.each_pair end end |
#empty? ⇒ Boolean
selfに要素がないかどうかを返します。
Returns whether self has no item.
232 233 234 |
# File 'lib/multiset.rb', line 232 def empty? @entries.empty? end |
#eql?(other) ⇒ Boolean
:nodoc:
194 195 196 197 198 199 200 |
# File 'lib/multiset.rb', line 194 def eql?(other) # :nodoc: if self.hash == other.hash self == other else false end end |
#find(ifnone = nil, &block) ⇒ Object Also known as: detect
ブロックにselfの要素(重複なし)を順次与え、最初に結果が真であった要素を返します。見つからなかった場合は、ifnoneが指定されている場合は ifnone.call し、そうでなければnilを返します。ブロックを与えなかった場合、そのためのEnumeratorを返します。
Gives all items in self (without duplication) to given block, and returns the first item that makes true the result of the block. If none of the items make it true, ifnone.call is executed if ifnone is specified, otherwise nil is returned. If no block is given, corresponding Enumerator is returned.
844 845 846 847 848 849 850 |
# File 'lib/multiset.rb', line 844 def find(ifnone = nil, &block) # :yields: item if block find_(ifnone, &block) else self.to_enum(:find_, ifnone) end end |
#find_all(&block) ⇒ Object Also known as: select
ブロックにselfの要素(重複なし)を順次与え、結果が真であった要素を集めた多重集合を返します。ブロックを与えなかった場合、そのためのEnumeratorを返します。
Gives all items in self (without duplication) to given block, and returns the Multiset by items that makes true the result of the block. If no block is given, corresponding Enumerator is returned.
888 889 890 891 892 893 894 |
# File 'lib/multiset.rb', line 888 def find_all(&block) # :yields: item if block find_all_(&block) else self.to_enum(:find_all_, ifnone) end end |
#find_all_with(&block) ⇒ Object Also known as: select_with
Multiset#find_allと同じですが、ブロックにはselfの要素とその個数の組が与えられます。
The same as Multiset#find_all, but pairs of (non-duplicate) items and their counts are given to the block.
909 910 911 912 913 914 915 |
# File 'lib/multiset.rb', line 909 def find_all_with(&block) # :yields: item if block find_all_with_(&block) else self.to_enum(:find_all_with_, ifnone) end end |
#find_all_with_(&block) ⇒ Object
:nodoc:
918 919 920 921 922 923 924 |
# File 'lib/multiset.rb', line 918 def find_all_with_(&block) # :nodoc: ret = Multiset.new @entries.each_pair do |item, count| ret.renew_count(item, count) if yield(item, count) end ret end |
#find_with(ifnone = nil, &block) ⇒ Object Also known as: detect_with
Multiset#findと同じですが、ブロックにはselfの要素とその個数の組が与えられます。
The same as Multiset#find, but pairs of (non-duplicate) items and their counts are given to the block.
864 865 866 867 868 869 870 |
# File 'lib/multiset.rb', line 864 def find_with(ifnone = nil, &block) # :yields: item if block find_with_(ifnone, &block) else self.to_enum(:find_with_, ifnone) end end |
#flatten ⇒ Object
self中に含まれる多重集合を平滑化したものを返します。
Generates a multiset such that multisets in self are flattened.
707 708 709 710 711 712 713 714 715 716 717 |
# File 'lib/multiset.rb', line 707 def flatten ret = Multiset.new self.each do |item| if item.kind_of?(Multiset) ret += item.flatten else ret << item end end ret end |
#flatten! ⇒ Object
self中に含まれる多重集合を平滑化します。平滑化した多重集合が1つでもあればselfを、そうでなければnilを返します。
Flattens multisets in self. Returns self if any item is flattened, nil otherwise.
726 727 728 729 730 731 732 733 734 735 736 |
# File 'lib/multiset.rb', line 726 def flatten! ret = nil self.to_a.each do |item| if item.kind_of?(Multiset) self.delete(item) self.merge!(item.flatten) ret = self end end ret end |
#grep(pattern) ⇒ Object
patternの条件を満たした(pattern === item)要素のみを集めた多重集合を返します。ブロックが与えられている場合は、さらにその結果を適用した結果を返します。
Collects items in self satisfying pattern (pattern === item). If a block is given, the items are converted by the result of the block.
932 933 934 935 936 937 938 939 940 |
# File 'lib/multiset.rb', line 932 def grep(pattern) ret = Multiset.new @entries.each_pair do |item, count| if pattern === item ret.add((block_given? ? yield(item) : item), count) end end ret end |
#group_by ⇒ Object Also known as: classify
selfの要素を、与えられたブロックからの返り値によって分類します。ブロックからの返り値をキーとして値を対応付けたMultimapを返します。
Classify items in self by returned value from block. Returns a Multimap whose values are associated with keys. Keys’ are defined by returned value from given block.
812 813 814 815 816 817 818 |
# File 'lib/multiset.rb', line 812 def group_by ret = Multimap.new @entries.each_pair do |item, count| ret[yield(item)].add(item, count) end ret end |
#group_by_with ⇒ Object Also known as: classify_with
Multiset#group_byと同様ですが、ブロックには要素とその個数の組が与えられます。
Same as Multiset#group_by, but the pairs of (non-duplicate) items and their counts are given to block.
824 825 826 827 828 829 830 |
# File 'lib/multiset.rb', line 824 def group_by_with ret = Multimap.new @entries.each_pair do |item, count| ret[yield(item, count)].add(item, count) end ret end |
#hash ⇒ Object
:nodoc:
186 187 188 189 190 191 192 |
# File 'lib/multiset.rb', line 186 def hash # :nodoc: val = 0 @entries.each_pair do |item, count| val += item.hash * count end val end |
#include?(item) ⇒ Boolean Also known as: member?
itemがself中に含まれているかを返します。
Returns whether self has item.
256 257 258 |
# File 'lib/multiset.rb', line 256 def include?(item) @entries.has_key?(item) end |
#inject_with(init) ⇒ Object
ブロックに「1回前のブロック呼び出しの返り値」「selfの要素」「その個数」の3つ組を順次与え、最後にブロックを呼んだ結果を返します。ただし「1回前のブロック呼び出しの返り値」は、1回目のブロック呼び出しの際については、代わりにinitの値が与えられます。
Enumerable#injectと異なり、initは省略できません。またブロックの代わりにSymbolを与えることもできません。
Three elements are given to the block for each (non-duplicate) items: the last result of the block, the item and its count. As for the first block call, the first argument is init. The result of the last block call is returned.
Different from Enumerable#inject, init cannot be omitted. In addition, Symbol cannot be given instead of a block.
956 957 958 959 960 961 |
# File 'lib/multiset.rb', line 956 def inject_with(init) @entries.each_pair do |item, count| init = yield(init, item, count) end init end |
#inspect ⇒ Object
:nodoc:
306 307 308 309 310 311 |
# File 'lib/multiset.rb', line 306 def inspect # :nodoc: buf = "#<Multiset:" buf += self.to_s(', ') buf += '>' buf end |
#items ⇒ Object
selfに含まれている要素(重複は除く)からなる配列を返します。
Returns an array with all items in self, without duplication.
239 240 241 |
# File 'lib/multiset.rb', line 239 def items @entries.keys end |
#listing(delim = "\n") ⇒ Object
selfの全要素を(重複を許して)並べた文字列を返します。要素間の区切りはdelimの値を用い、各要素の表示形式は与えられたブロックの返り値(なければObject#inspect)を用います。
Lists all items with duplication in self. Items are deliminated with delim, and items are converted to string in the given block. If block is omitted, Object#inspect is used.
269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/multiset.rb', line 269 def listing(delim = "\n") buf = '' init = true self.each do |item| if init init = false else buf += delim end buf += block_given? ? yield(item).to_s : item.inspect end buf end |
#map ⇒ Object Also known as: collect
selfの各要素(重複なし)をブロックに与え、返り値を集めたものからなる多重集合を生成します。
Gives all items in self (without duplication) to given block, and generates a new multiset whose values are returned value from the block.
634 635 636 637 638 639 640 |
# File 'lib/multiset.rb', line 634 def map # :yields: item ret = Multiset.new @entries.each_pair do |item, count| ret.add(yield(item), count) end ret end |
#map!(&block) ⇒ Object Also known as: collect!
Multiset#mapと同様ですが、結果として生成される多重集合でselfが置き換えられます。selfを返します。
Same as Multiset#map, but replaces self by resulting multiset. Returns self.
648 649 650 651 |
# File 'lib/multiset.rb', line 648 def map!(&block) # :yields: item self.replace(self.map(&block)) self end |
#map_with ⇒ Object Also known as: collect_with
selfの要素(重複なし)とその個数の組をブロックに与えます。ブロックから2要素の配列を受け取り、前者を要素、後者をその個数とした多重集合を生成します。
Gives all pairs of (non-duplicate) items and their numbers in self to given block. The block must return an array of two items. Generates a new multiset whose values and numbers are the first and second item of returned array, respectively.
662 663 664 665 666 667 668 669 |
# File 'lib/multiset.rb', line 662 def map_with ret = Multiset.new @entries.each_pair do |item, count| val = yield(item, count) ret.add(val[0], val[1]) end ret end |
#map_with! ⇒ Object Also known as: collect_with!
Multiset#map_withと同様ですが、結果として生成される多重集合でselfが置き換えられます。selfを返します。
Same as Multiset#map_with, but replaces self by resulting multiset. Returns self.
677 678 679 680 681 682 683 684 |
# File 'lib/multiset.rb', line 677 def map_with! self.to_hash.each_pair do |item, count| self.delete(item, count) val = yield(item, count) self.add(val[0], val[1]) end self end |
#max(&block) ⇒ Object
最大の要素を返します。要素が存在しない場合はnilを返します。ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。
Returns the largest item, or nil if no item is stored in self. If a block is given, their order is judged by giving two items to the block.
969 970 971 |
# File 'lib/multiset.rb', line 969 def max(&block) # :yields: a, b @entries.keys.max(&block) end |
#max_by(&block) ⇒ Object
ブロックの値を評価した結果が最大になるような要素を返します。要素が存在しない場合はnilを返します。
Returns the largest item, or nil if no item is stored in self.
996 997 998 |
# File 'lib/multiset.rb', line 996 def max_by(&block) # :yields: item @entries.keys.max_by(&block) end |
#max_by_with(&block) ⇒ Object
Multiset#max_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。
Same as Multiset#min, but pairs of (non-duplicated) items and their counts are given to the block.
1046 1047 1048 1049 |
# File 'lib/multiset.rb', line 1046 def max_by_with(&block) # :yields: item tmp = @entries.each_pair.max_by(&block) tmp ? tmp[0] : nil # if @entries is not empty, tmp must be a two-element array end |
#max_with ⇒ Object
Multiset#max と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の4引数が与えられます。
Same as Multiset#max, but four arguments: “item 1”, “number of item 1”, “item 2” and “number of item 2” are given to the block.
1020 1021 1022 1023 |
# File 'lib/multiset.rb', line 1020 def max_with # :yields: item1, count1, item2, count2 tmp = @entries.each_pair.max{ |a, b| yield(a[0], a[1], b[0], b[1]) } tmp ? tmp[0] : nil end |
#merge(other) ⇒ Object Also known as: +
selfとotherの要素を合わせた多重集合を返します。
Returns merged multiset of self and other.
494 495 496 497 498 499 500 |
# File 'lib/multiset.rb', line 494 def merge(other) ret = self.dup other.each_pair do |item, count| ret.add(item, count) end ret end |
#merge!(other) ⇒ Object
selfにotherの要素を追加します。selfを返します。
Merges other to self. Returns self.
508 509 510 511 512 513 |
# File 'lib/multiset.rb', line 508 def merge!(other) other.each_pair do |item, count| self.add(item, count) end self end |
#min(&block) ⇒ Object
最小の要素を返します。要素が存在しない場合はnilを返します。ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。
Returns the smallest item, or nil if no item is stored in self. If a block is given, their order is judged by giving two items to the block.
979 980 981 |
# File 'lib/multiset.rb', line 979 def min(&block) # :yields: a, b @entries.keys.min(&block) end |
#min_by(&block) ⇒ Object
ブロックの値を評価した結果が最小になるような要素を返します。要素が存在しない場合はnilを返します。
Returns the smallest item, or nil if no item is stored in self.
1004 1005 1006 |
# File 'lib/multiset.rb', line 1004 def min_by(&block) # :yields: item @entries.keys.min_by(&block) end |
#min_by_with(&block) ⇒ Object
Multiset#min_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。
Same as Multiset#max, but pairs of (non-duplicated) items and their counts are given to the block.
1054 1055 1056 1057 |
# File 'lib/multiset.rb', line 1054 def min_by_with(&block) # :yields: item tmp = @entries.each_pair.min_by(&block) tmp ? tmp[0] : nil # if @entries is not empty, tmp must be a two-element array end |
#min_with ⇒ Object
Multiset#min と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の4引数が与えられます。
Same as Multiset#min, but four arguments: “item 1”, “number of item 1”, “item 2” and “number of item 2” are given to the block.
1029 1030 1031 1032 |
# File 'lib/multiset.rb', line 1029 def min_with # :yields: item1, count1, item2, count2 tmp = @entries.each_pair.min{ |a, b| yield(a[0], a[1], b[0], b[1]) } tmp ? tmp[0] : nil end |
#minmax(&block) ⇒ Object
最小の要素と最大の要素の組を返します。ブロックが与えられた場合は、要素間の大小判定を、ブロックに2つの要素を与えることで行います。
Returns the pair consisting of the smallest and the largest item. If a block is given, their order is judged by giving two items to the block.
988 989 990 |
# File 'lib/multiset.rb', line 988 def minmax(&block) # :yields: a, b @entries.keys.minmax(&block) end |
#minmax_by(&block) ⇒ Object
ブロックの値を評価した結果が最小になる要素と最大になる要素の組を返します。要素が存在しない場合はnilを返します。
Returns the pair consisting of the smallest and the largest item.
1012 1013 1014 |
# File 'lib/multiset.rb', line 1012 def minmax_by(&block) # :yields: item @entries.keys.minmax_by(&block) end |
#minmax_by_with(&block) ⇒ Object
Multiset#minmax_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。
Same as Multiset#minmax, but pairs of (non-duplicated) items and their counts are given to the block.
1062 1063 1064 1065 |
# File 'lib/multiset.rb', line 1062 def minmax_by_with(&block) # :yields: item tmp = @entries.each_pair.minmax_by(&block) tmp[0] ? [tmp[0][0], tmp[1][0]] : nil end |
#minmax_with ⇒ Object
Multiset#minmax と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の4引数が与えられます。
Same as Multiset#minmax, but four arguments: “item 1”, “number of item 1”, “item 2” and “number of item 2” are given to the block.
1038 1039 1040 1041 |
# File 'lib/multiset.rb', line 1038 def minmax_with # :yields: item1, count1, item2, count2 tmp = @entries.each_pair.minmax{ |a, b| yield(a[0], a[1], b[0], b[1]) } tmp ? [tmp[0][0], tmp[1][0]] : nil end |
#proper_subset?(other) ⇒ Boolean
selfがotherに真に含まれているかどうかを返します。「真に」とは、両者が一致する場合は含めないことを示します。
Returns whether self is a proper subset of other.
470 471 472 473 474 475 |
# File 'lib/multiset.rb', line 470 def proper_subset?(other) unless other.instance_of?(Multiset) raise ArgumentError, "Argument must be a Multiset" end self.subset?(other) && self != other end |
#proper_superset?(other) ⇒ Boolean
selfがotherを真に含んでいるかどうかを返します。「真に」とは、両者が一致する場合は含めないことを示します。
Returns whether self is a proper superset of other.
449 450 451 452 453 454 |
# File 'lib/multiset.rb', line 449 def proper_superset?(other) unless other.instance_of?(Multiset) raise ArgumentError, "Argument must be a Multiset" end self.superset?(other) && self != other end |
#reject ⇒ Object
ブロックにselfの要素(重複なし)を順次与え、結果が偽であった要素のみを集めたMultisetを返します。
Gives all items in self (without duplication) to given block, and returns a multiset collecting the items whose results in the block are false.
743 744 745 746 747 748 749 |
# File 'lib/multiset.rb', line 743 def reject ret = Multiset.new @entries.each_pair do |item, count| ret.renew_count(item, count) unless yield(item) end ret end |
#reject! ⇒ Object
Multiset#delete_ifと同じですが、要素が1つも削除されなければnilを返します。
Same as Multiset#delete_if, but returns nil if no item is deleted.
767 768 769 770 771 772 773 774 775 776 |
# File 'lib/multiset.rb', line 767 def reject! ret = nil @entries.each_pair do |item, count| if yield(item) self.delete_all(item) ret = self end end ret end |
#reject_with ⇒ Object
ブロックにselfの要素(重複なし)と個数の組を順次与え、結果が偽であった要素のみを集めたMultisetを返します。
Gives all pairs of (non-duplicate) items and counts in self to given block, and returns a multiset collecting the items whose results in the block are false.
756 757 758 759 760 761 762 |
# File 'lib/multiset.rb', line 756 def reject_with ret = Multiset.new @entries.each_pair do |item, count| ret.renew_count(item, count) unless yield(item, count) end ret end |
#renew_count(item, number) ⇒ Object
selfに含まれるitemの個数をnumber個にします。numberが負の数であった場合は、number = 0とみなします。成功した場合はselfを、失敗した場合はnilを返します。
Sets number of item to number in self. If number is negative, treats as number = 0. Returns self if succeeded, nil otherwise.
363 364 365 366 367 368 369 370 371 372 |
# File 'lib/multiset.rb', line 363 def renew_count(item, number) return nil if number == nil n = number.to_i if n > 0 @entries[item] = n else @entries.delete(item) end self end |
#replace(other) ⇒ Object
selfの内容をotherのものに置き換えます。selfを返します。
Replaces self by other. Returns self.
213 214 215 216 217 218 219 |
# File 'lib/multiset.rb', line 213 def replace(other) @entries.clear other.each_pair do |item, count| self.renew_count(item, count) end self end |
#sample ⇒ Object Also known as: rand
selfの要素を無作為に1つ選んで返します。すべての要素は等確率で選ばれます。空のmultisetに対して呼び出した場合はnilを返します。
Returns one item in self randomly. All items are selected with the same probability. Returns nil in case the multiset is empty.
694 695 696 697 698 699 700 701 |
# File 'lib/multiset.rb', line 694 def sample return nil if empty? pos = Kernel.rand(self.size) @entries.each_pair do |item, count| pos -= count return item if pos < 0 end end |
#size ⇒ Object Also known as: length
selfに含まれている要素数を返します。
Returns number of all items in self.
224 225 226 |
# File 'lib/multiset.rb', line 224 def size @entries.inject(0){ |sum, item| sum += item[1] } end |
#sort(&block) ⇒ Object
selfの要素を並び替えた配列を生成します。
Generates an array by sorting the items in self.
1070 1071 1072 1073 1074 1075 1076 |
# File 'lib/multiset.rb', line 1070 def sort(&block) # :yields: a, b ret = [] @entries.keys.sort(&block).each do |item| ret.fill(item, ret.length, @entries[item]) end ret end |
#sort_by(&block) ⇒ Object
Multiset#sortと同様ですが、ブロックには1つの要素が与えられ、その値が小さいものから順に並びます。
Same as Multiset#sort, but only one item is given to the block.
1081 1082 1083 1084 1085 1086 1087 |
# File 'lib/multiset.rb', line 1081 def sort_by(&block) # :yields: item ret = [] @entries.keys.sort_by(&block).each do |item| ret.fill(item, ret.length, @entries[item]) end ret end |
#sort_by_with ⇒ Object
Multiset#sort_by と同様ですが、ブロックには要素(重複なし)とその出現数の組が与えられます。
Same as Multiset#sort_by, but pairs of (non-duplicated) items and their counts are given to the block.
1104 1105 1106 1107 1108 1109 1110 |
# File 'lib/multiset.rb', line 1104 def sort_by_with # :yields: item1, count1, item2, count2 ret = [] @entries.each_pair.sort_by{ |a| yield(*a) }.each do |item_count| ret.fill(item_count[0], ret.length, item_count[1]) end ret end |
#sort_with ⇒ Object
Multiset#sort と同様ですが、ブロックには「要素1」「要素1の出現数」「要素2」「要素2の出現数」の4引数が与えられます。
Same as Multiset#sort, but four arguments: “item 1”, “number of item 1”, “item 2” and “number of item 2” are given to the block.
1093 1094 1095 1096 1097 1098 1099 |
# File 'lib/multiset.rb', line 1093 def sort_with # :yields: item1, count1, item2, count2 ret = [] @entries.each_pair.sort{ |a, b| yield(a[0], a[1], b[0], b[1]) }.each do |item_count| ret.fill(item_count[0], ret.length, item_count[1]) end ret end |
#subset?(other) ⇒ Boolean
selfがotherに含まれているかどうかを返します。
Returns whether self is a subset of other.
459 460 461 462 463 464 |
# File 'lib/multiset.rb', line 459 def subset?(other) unless other.instance_of?(Multiset) raise ArgumentError, "Argument must be a Multiset" end compare_set_with(other){ |s, o| s <= o } end |
#subtract(other) ⇒ Object Also known as: -
selfからotherの要素を取り除いた多重集合を返します。
Returns multiset such that items in other are removed from self.
518 519 520 521 522 523 524 |
# File 'lib/multiset.rb', line 518 def subtract(other) ret = self.dup other.each_pair do |item, count| ret.delete(item, count) end ret end |
#subtract!(other) ⇒ Object
selfからotherの要素を削除します。selfを返します。
Removes items in other from self. Returns self.
532 533 534 535 536 537 |
# File 'lib/multiset.rb', line 532 def subtract!(other) other.each_pair do |item, count| self.delete(item, count) end self end |
#superset?(other) ⇒ Boolean
selfがotherを含んでいるかどうかを返します。
Returns whether self is a superset of other.
438 439 440 441 442 443 |
# File 'lib/multiset.rb', line 438 def superset?(other) unless other.instance_of?(Multiset) raise ArgumentError, "Argument must be a Multiset" end compare_set_with(other){ |s, o| s >= o } end |
#to_a ⇒ Object
selfを配列に変換して返します。
Converts self to an array.
178 179 180 181 182 183 184 |
# File 'lib/multiset.rb', line 178 def to_a ret = [] @entries.each_pair do |item, count| ret.concat Array.new(count, item) end ret end |
#to_hash ⇒ Object
selfをHashに変換して返します。生成されるハッシュの構造については、Hash#to_multisetをご覧下さい。
Converts self to a Hash. See Hash#to_multiset about format of generated hash.
146 147 148 |
# File 'lib/multiset.rb', line 146 def to_hash @entries.dup end |
#to_s(delim = "\n") ⇒ Object
selfの要素と要素数の組を並べた文字列を返します。要素間の区切りはdelimの値を用い、各要素の表示形式は与えられたブロックの返り値(なければObject#inspect)を用います。
Lists all items without duplication and its number in self. Items are deliminated with delim, and items are converted to string in the given block. If block is omitted, Object#inspect is used.
291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/multiset.rb', line 291 def to_s(delim = "\n") buf = '' init = true @entries.each_pair do |item, count| if init init = false else buf += delim end item_tmp = block_given? ? yield(item) : item.inspect buf += "\##{count} #{item_tmp}" end buf end |
#to_set ⇒ Object
selfを通常の集合(Ruby標準添付のSet)に変換したものを返します。
このメソッドを呼び出すと、require "set"が行われます。
なおSetをMultisetに変換するには、Multiset.new(instance_of_set)で可能です。
Converts self to ordinary set (The Set class attached to Ruby by default).
require "set" is performed when this method is called.
To convert Set to Multiset, use Multiset.new(instance_of_set).
170 171 172 173 |
# File 'lib/multiset.rb', line 170 def to_set require "set" Set.new(@entries.keys) end |
#|(other) ⇒ Object
selfとotherの和集合からなる多重集合を返します。
Returns union of self and other.
553 554 555 556 557 558 559 |
# File 'lib/multiset.rb', line 553 def |(other) ret = self.dup other.each_pair do |item, count| ret.renew_count(item, [self.count(item), count].max) end ret end |