Reverse reference - Multiset Library for Ruby

Multiset Library for Rubyの逆引きリファレンスです。


多重集合を作る

特定の要素を含む多重集合を作る

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>

配列から多重集合を作る

Enumerableであるオブジェクトであれば、配列以外でも指定できます。

 irb(main):???:0> arr = [:a, :a, :b, :c, :b]
 => [:a, :a, :b, :c, :b]
 irb(main):???:0> Multiset.new(arr)
 => #<Multiset:#2 :b, #1 :c, #2 :a>

要素と個数の組から多重集合を作る

 irb(main):???:0> hash = { :a => 2, :b => 2, :c => 1 }
 => {:b=>2, :c=>1, :a=>2}
 irb(main):???:0> hash.to_multiset
 => #<Multiset:#2 :b, #1 :c, #2 :a>

別の多重集合の複製を作る

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :a, #2 :b, #1 :c>
 irb(main):???:0> ms2 = ms.dup
 => #<Multiset:#2 :a, #2 :b, #1 :c>
 irb(main):???:0> ms == ms2
 => true
 irb(main):???:0> ms.object_id == ms2.object_id
 => false

自身を別の多重集合の複製にする

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :a, #2 :b, #1 :c>
 irb(main):???:0> ms.replace Multiset[:x, :x, :y]
 => #<Multiset:#2 :x, #1 :y>

多重集合を編集する

多重集合に要素を追加する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.add(:a)
 => #<Multiset:#2 :b, #1 :c, #3 :a>
 irb(main):???:0> ms << :b
 => #<Multiset:#3 :b, #1 :c, #3 :a>

同一の要素を複数追加するには、addメソッドの第2引数を指定します。

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.add(:c, 6)
 => #<Multiset:#2 :b, #7 :c, #2 :a>

多重集合から特定の要素を削除する

addメソッドと同様、deleteメソッドでも第2引数が指定できます。またdelete_allメソッドで該当する要素をすべて削除します。

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.delete(:a)
 => #<Multiset:#2 :b, #1 :c, #1 :a>
 irb(main):???:0> ms.delete(:b, 2)
 => #<Multiset:#1 :c, #1 :a>
 irb(main):???:0> ms.delete_all(:c)
 => #<Multiset:#1 :a>

多重集合からある条件を満たす要素を削除する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.delete_if{ |item| item.to_s < "c" }
 => #<Multiset:#1 :c>
 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.delete_with{ |item, count| count < 2 }
 => #<Multiset:#2 :b, #2 :a>

ある要素が多重集合中に含まれる数を変更する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.renew_count(:c, 10)
 => #<Multiset:#2 :b, #10 :c, #2 :a>

2つの多重集合を合併する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b] + Multiset[:a, :b, :x, :y]
 => #<Multiset:#3 :a, #3 :b, #1 :x, #1 :c, #1 :y>

多重集合についての情報を得る

多重集合に含まれる要素の数を得る

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].size
 => 5
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].count(:a)
 => 2

多重集合が空であるか調べる際は、empty?メソッドを使う。

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].empty?
 => false
 irb(main):???:0> Multiset[].empty?
 => true

多重集合に特定の要素が存在するか調べる

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].include?(:a)
 => true
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].include?(:x)
 => false

要素をランダムに1つ取得する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].rand
 => :b
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].rand
 => :a

多重集合を別の型に変換する

配列に変換する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].to_a
 => [:b, :b, :c, :a, :a]

重複する要素を除去する場合

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].items
 => [:b, :c, :a]

ハッシュに変換する

キーが要素、値が個数となります。

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].to_hash
 => {:b=>2, :c=>1, :a=>2}

通常の集合(Ruby標準添付のSet)に変換する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].to_set
 => #<Set: {:a, :b, :c}>

多重集合の全要素について処理する

1つずつ処理する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.each { |i| p i }
 :b
 :b
 :c
 :a
 :a
 => #<Multiset:#2 :b, #1 :c, #2 :a>

重複を除去して1つずつ処理する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.each_item { |i| p i }
 :b
 :c
 :a
 => #<Multiset:#2 :b, #1 :c, #2 :a>

要素と個数の組について処理する

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :b, #1 :c, #2 :a>
 irb(main):???:0> ms.each_pair { |i, c| p [i, c] }
 [:b, 2]
 [:c, 1]
 [:a, 2]
 => #<Multiset:#2 :b, #1 :c, #2 :a>

全要素を特定の処理によって一斉に置き換える

 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :a, #2 :b, #1 :c>
 irb(main):???:0> ms.map{ |i| item.to_s }
 => #<Multiset:#2 "a", #2 "b", #1 "c">
 irb(main):???:0> ms = Multiset[:a, :a, :b, :c, :b]
 => #<Multiset:#2 :a, #2 :b, #1 :c>
 irb(main):???:0> ms.map_with{ |i, c| [item.to_s, count * 2] }
 => #<Multiset:#4 "a", #4 "b", #2 "c">

2つの多重集合を比較する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b] == Multiset[:a, :b, :c, :b, :a]
 => true
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b] == Multiset[:a, :b, :c, :b]
 => false
 irb(main):???:0> Multiset[:a, :a, :b, :c].subset?(Multiset[:a, :b, :c, :b, :a])
 => true
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].superset?(Multiset[:a, :b, :c, :b])
 => true

この他にも、proper_subset?proper_superset?といったメソッドがあります。

多重集合の要素をいくつかのグループに分類する

 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].classify{ |i| i.to_s < "c" }
 => {false=>#<Multiset:#1 :c>, true=>#<Multiset:#2 :a, #2 :b>}
 irb(main):???:0> Multiset[:a, :a, :b, :c, :b].classify_with{ |i, c| c }
 => {1=>#<Multiset:#1 :c>, 2=>#<Multiset:#2 :a, #2 :b>}