Ruby

Setクラスでの集合

More than 1 year has passed since last update.

rubyには集合を表すクラス、Setがあります。
その使い方まとめです:moyai:

ちなみに、Arrayでも集合のための処理が用意されています。(rubyのArrayで集合(和集合・積集合・差集合・対称差集合・補集合)

intro

以下のように作れます。

require 'set'
p Set[1, 2] #=> #<Set: {1, 2}>
p Set.new                      #=> #<Set: {}>
p Set.new([1, 2])              #=> #<Set: {1, 2}>
p Set.new([1, 2]) {|o| o * 2}  #=> #<Set: {2, 4}>

ちなみに、重複は除きます。

require 'set'
Set[10, 10, 20, 30]
=> #<Set: {10, 20, 30}>

Arrayからの変換とArrayへの変換

require 'set'
array = [10,20,30] # => [10, 20, 30]
set = Set[*array] # => #<Set: {10, 20, 30}>
set.to_a # => [10, 20, 30]

Enumerableから変換

Enumerable#to_setを使うことで
Enumerableからも作れます。

require 'set'
p [30, 10, 20].to_set
#=> #<Set: {30, 10, 20}>
p [30, 10, 20].to_set(SortedSet) #SortedSetでソートできる
#=> #<SortedSet: {10, 20, 30}>
p [30, 10, 20].to_set {|num| num / 10} #値を処理してからsetする
#=> #<Set: {3, 1, 2}>
p (1..3).to_set
#=> #<Set: {1, 2, 3}>

和集合「+,|,union

Set[10, 20, 30] + Set[10, 20, 40]
=> #<Set: {10, 20, 30, 40}>
Set[10, 20, 30] | Set[10, 20, 40]
=> #<Set: {10, 20, 30, 40}>
Set[10, 20, 30].union(Set[10, 20, 40])
=> #<Set: {10, 20, 30, 40}>

積集合「&, intersection

Set[10, 20, 30] & Set[10, 20, 40]
=> #<Set: {10, 20}>
Set[10, 20, 30].intersection(Set[10, 20, 40])
=> #<Set: {10, 20}>

差集合「-, difference

require 'set'
p Set[10, 20, 30] - Set[10, 20, 40]
#=> #<Set: {30}>
Set[10, 20, 30].difference(Set[10, 20, 40])
=> #<Set: {30}>

subtractを使えば、
元の集合からenumで与えられた要素を削除することもできます。

Set[10, 20, 30].subtract([10, 20, 40])
# set #=> #<Set: {30}>

発展

対称差集合「^

require 'set'
p Set[10, 10, 20, 30] ^ Set[10, 30, 40]
#=> #<Set: {40, 20}>

等しいか比較

ちなみに、順序は関係ありません。

require 'set'
Set[10,20] == Set[10,20] #=> true
Set[10,20] == Set[20,10] #=> true
Set[10,20] == Set[10,20,30] #=> false

含有関係「superset?, proper_superset?

superset?は、
2つの集合が等しい場合にもtrueになる。

require 'set'
s = Set[1, 2, 3]
p s.superset?(Set[1, 2]) #=> true
p s.superset?(Set[1, 4]) #=> false
p s.superset?(Set[1, 2, 3]) #=> true

proper_superset?は、
2つの集合が等しい場合falseになる

require 'set'
s = Set[1, 2, 3]
p s.proper_superset?(Set[1, 2]) #=> true
p s.proper_superset?(Set[1, 4]) #=> false
p s.proper_superset?(Set[1, 2, 3]) #=> false

素であるかをチェック

require 'set'
p Set[1, 2, 3].disjoint? Set[3, 4] # => false
p Set[1, 2, 3].disjoint? Set[4, 5] # => true

共通部分があるかどうかをチェック

require 'set'
p Set[1, 2, 3].intersect?(Set[3, 4])  # => true
p Set[1, 2, 3].intersect?(Set[4, 5])  # => false