[Ruby]Enumerableモジュールのメソッド

1年くらい前にRubyの勉強のためにEnumerableモジュールの便利メソッドをまとめたもの

参考
・[パーフェクトRuby](https://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88Ruby-PERFECT-6-Ruby%E3%82%B5%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%BA/dp/4774158798/ref=sr_1_2?ie=UTF8&qid=1493615214&sr=8-2&keywords=%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88Ruby)
・https://docs.ruby-lang.org/ja/latest/class/Enumerable.html

## 繰り返し
each_with_index
繰り返しの度にインクリメントされる値と一緒に繰り返す

``` ruby
%w(Alpha Bravo Charlie).each_with_index do |code, index|
	puts "#{index}: #{code}"
end # => "0: Alpha" "1: Bravo" "2: Charlie"
```

reverse_each
末尾から逆順に繰り返す

``` ruby
(1..3).reverse_each { |val| puts val } # => 3 2 1

```

each_slice
要素をn個ずつ区切って繰り返す

``` ruby
(1..5).each_slice 2 { |a, b| p [a, b] }
# => [1, 2] [3, 4] [5, nil]

```
each_cons
n個の連続した要素を１つずつずらしながら繰り返す

``` ruby
(1..4).each_cons 3 { |a, b, c| p [a, b, c] }
# => [1, 2, 3] [2, 3, 4] nil
```
cycle
レシーバの要素を先頭から末尾まで繰り返しを永遠に行う

``` ruby
(1..3).cycle { |n| p n } # => 1 2 3 1 2 …
```

## プロックを評価した結果の配列
map
ブロックの戻り値を集めた配列を返す

``` ruby
['ruby', 'rails'].map { |str| str.upcase } # => ["RUBY", "RAILS"]
```
## ブロックの返り値を連結した配列
flat_map
各要素をブロックに渡し、その返り値を連結した配列を返す

``` ruby
[[1,2], [3,4]].flat_map{|i| i.map{|j| j * 2 }} # => [2,4,6,8]
```
## 複数の要素を組み合わせる
zip
複数の要素を組み合わせて配列の配列を作る

``` ruby
nums = (1..4)
langs = %w(ruby python java)
arr = [true, false]

nums.zip(arr, langs) 
# => [[1, true, "ruby"], [2, false, "python"], [3, nil, "java"], [4, nil, nil]]

arr.zip(nums, langs)
# => [[true, 1, "ruby"], [false, 2, "python"]]
```

## 要素が特定の条件を満たしているか
all?
すべての要素が真ならtrue
none?
すべての要素が偽ならtrue
any?
1つでも要素が真ならtrue
one?
1つだけ要素が真ならtrue

``` ruby
[true, true, true].all? # => true
[true, true, false].all? # => false

[false, false, false].none? # => true
[true, true, false].none? # => false

[false, false, true].any? # => true
[false, false, false].any? # => false

[false, false, true].one? # => true
[true, true, false].one? # => false
```
## 部分的な要素の取得
grep
正規表現にマッチする各要素を検索する
 
``` ruby
 %w(Alpha Bravo Charlie).grep(/l/i)
# => ["Alpha", "Charlie"]
```

detect(find)
最初に真となった要素を返す

select
真となった要素をすべて返す

``` ruby
array = [4, 6, 2, 1]

array.detect {|v| v.even? } # => 4
array.select {|v| v.even? } # => 4 6 2
```

take
先頭から任意の数の要素を配列として返す

drop
先頭から任意の数の要素をスキップして残りの要素を配列として返す

``` ruby
array = %w(a b c d e)

array.take(2) # => ["a", "b"]
array.drop(2) # => ["c", "d", "e"]
```

take_while
ブロックが最初に偽を返すまでの要素の配列を返す

drop_while
ブロックが最初に偽を返してからの要素の配列を返す

``` ruby
array = %w(a b c d e)

array.take_while { |n| n != 'c' } # => ["a", "b"]
array.drop_while { |n| n != 'c' } # => ["c", "d", "e"]
```

## 畳み込み演算
inject(reduce)
ブロックを受け取りブロックは各要素に対して実行する

``` ruby
[1, 2, 5].inject do |result, num|
	result + num
end # => 8

[1, 2, 5].inject(:+) # => 8
```

## 繰り返しとオブジェクトの更新
each_with_object
引数のオブジェクトを繰り返しの度にブロック引数として渡し最終的には戻り値とする。

``` ruby
numbers = [4, 3, 9]
numbers.each_with_object([]) do |number, result|
	result << number + 3
end
```

## 要素のグルーピング
group_by
ブロックを評価した結果の戻り値をキーにして新しいハッシュを返す
同一条件ごとに総まとめする。

``` ruby
array = [1, 'a', 2, 'b', 3, 'c']

array.group_by {|val| val.class }
# => {Integer=>[1, 2, 3], String=>["a", "b", "c"]}
```

partition
ブロックの戻り値が真か偽かによって分けた２つのグループを配列にして返す

``` ruby
array = [1, 'a', 2, 'b', 3, 'c']

array.partition {|val| val.is_a?(String) }
# => [["a", "b", "c"], [1, 2, 3]]
```

chunk
ブロックの戻り値ごとに要素の並びをまとめた配列を作る。
同一条件ごちに部分まとめする。

``` ruby
array = [1, 'a', 2, 'b', 3, 'c']

enum = array.chunk {|val| val.class }
enum.each {|key, arr| puts "#{key}: #{arr}" }

# 出力結果
Integer: [1]
String: ["a"]
Integer: [2]
String: ["b"]
Integer: [3]
String: ["c"]
```

slice_before
マッチ要素またはブロックが真を返した要素から次にマッチ or 真の要素までをチャンクしたものを返す。

``` ruby
[0, 2, 4, 1, 8, 3, 5, 7, 10].slice_before(&:even?).to_a
# => [[0], [2], [4, 1], [8, 3, 5, 7], [10]]
```

## 最小値と最大値
min
最小値を返す

max
最大値を返す

minmax
最小値と最大値を配列にして返す

``` ruby
range = (1..4)

range.min # => 1
range.max # => 4
range.minmax # => [1, 4]
```

min_by, max_by, minmax_by
ブロックを評価した結果で比較する

``` ruby
array = %w(a bb ccc)

array.min_by{|str| str.length } # => "a"
array.max_by{|str| str.length } # => "ccc"
array.minmax_by{|str| str.length } # => ["a", "ccc"]
```

## ソート
sort, sort_by
ソートした結果を新しい配列で返す

``` ruby
array = %w(cc a bbb)

# 要素でソート
array.sort # => ["a", "bbb", "cc"]

# 要素の長さでソート１
array.sort {|a, b| a.length <=> b.length } # => ["a", "cc", "bbb"]

# 要素の長さでソート２
array.sort_by { |str| str.length } # => ["a", "cc", "bbb"]
```
上記の場合、sort_byのほうが高速

sortは比較の度に2つの要素に対してメソッドを呼んでいる。
sort_byは要素ごとにメソッドを1回だけ呼んでいる。