Setクラスでの集合

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

ちなみに、Arrayでも集合のための処理が用意されています。（[rubyのArrayで集合（和集合・積集合・差集合・対称差集合・補集合）](http://qiita.com/namitop/items/be11c007da456ea95735)）

# intro

以下のように作れます。

```rb
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}>
```

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

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

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

```rb
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](https://docs.ruby-lang.org/ja/2.4.0/method/Enumerable/i/to_set.html)を使うことで
Enumerableからも作れます。

```rb
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`」

![](https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Venn0111.svg/300px-Venn0111.svg.png)

```rb
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`」

![](http://upload.wikimedia.org/wikipedia/commons/thumb/9/99/Venn0001.svg/300px-Venn0001.svg.png)

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


# 差集合「`-`, `difference `」

![](http://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/Venn0100.svg/300px-Venn0100.svg.png)

```rb
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で与えられた要素を削除することもできます。

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

# 発展

## 対称差集合「`^`」

![](http://upload.wikimedia.org/wikipedia/commons/thumb/4/46/Venn0110.svg/300px-Venn0110.svg.png) 

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

# 等しいか比較

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

```rb
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?`」

![](https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Venn_A_subset_B.svg/300px-Venn_A_subset_B.svg.png)

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

```rb
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`になる

```rb
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
```

# 素であるかをチェック

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

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

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