rubyを簡潔に書く方法にEnumerableモジュールが存在します。
今回は、Enumerableモジュールを用いて配列を操作してみます。
map, each
各要素に対して処理を行います。
mapとeachは実行後の返り値が異なります。mapはブロック文内の返り値、eachはブロックの引数を返します。
array = [1, 2, 3]
p array.each{|item| item * 2}
# [1, 2, 3]
p array.map{|item| item * 2}
# [2, 4, 6]
inject
injectは、配列の各要素をまとめた結果を扱いたい時に使います。each、mapとは異なり初期値を設定することができます。
a = [12, 4]
p a.inject(:gcd)
# 4
p a.inject(0){|sum, i| sum + i}
# 16
lambda関数を引数として処理することもできます。
add = ->(x,y){ x + y }
p a.inject &add
# 16
select, find
ブロック内の条件式が成立する要素を検索します。
要素が存在する場合には、selectは全ての要素を返し、findは先頭の要素を返します。
要素が存在しない場合には、selectは空配列、findはnilを返します。
a = [1, 2, 3]
p a.select{|i| i % 2 == 1}
# [1, 3]
p a.select{|i| i > 3}
# []
p a.find{|i| i % 2 == 1}
# 1
p a.find{|i| i > 3}
# nil
zip, flatten
zipは二つの配列を要素番号順に結合してくれます。
flattenは配列の入れ子構造を平らにしてくれます。また、階層を指定することもできます。
a = [11, 12]
b = [21, 22]
p a.zip(b)
# [[11, 21], [12, 22]]
a = [0, [1, [2]]]
p a.flatten
# [0, 1, 2]
p a.flatten(1)
# [0, 1, [2]]
all?, any?, none?, one?
条件判定を行う時に用い、all?は全件一致、any?は一部一致、none?は一致なし、oneは一件のみ存在する場合を検索します。
a = [1, 2, 3]
p a.all?{|i| i % 2 == 1} # false
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # false
p a.none?{|i| i % 2 == 1} # false
a = [1, 3, 5]
p a.all?{|i| i % 2 == 1} # true
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # false
p a.none?{|i| i % 2 == 1} # false
a = [2, 3, 4]
p a.all?{|i| i % 2 == 1} # false
p a.any?{|i| i % 2 == 1} # true
p a.one?{|i| i % 2 == 1} # true
p a.none?{|i| i % 2 == 1} # false
参考文献