Ruby Language
反復
サーチ…
各
Rubyには多くの種類の列挙子がありますが、最初から最も簡単な型の列挙子がeach
ます。私たちは1
から10
までの数字ごとにodd
またはodd
を印刷しeven
、 each
仕組みを示します。
基本的に、いわゆるblocks
を渡すには2つの方法がありblocks
。 block
は、呼び出されたメソッドによって実行されるコードの一部です。 each
メソッドは、呼び出されたオブジェクトのコレクションのすべての要素を呼び出すblock
をとります。
ブロックをメソッドに渡すには、2つの方法があります。
方法1:インライン
(1..10).each { |i| puts i.even? ? 'even' : 'odd' }
これはこれを解決するために非常に圧縮されたルビーの方法です。これを一枚ずつ壊しましょう。
-
(1..10)
は1
10
以下の範囲である。1
から10
排他的にしたければ、(1...10)
と書きます。 -
.each
は、それが動作しているオブジェクトのeach
要素を列挙する列挙子です。この場合、範囲内のeach
数値に作用します。 -
{ |i| puts i.even? ? 'even' : 'odd' }
はeach
ステートメントのブロックであり、それ自体はさらに細かく分割することができます。-
|i|
これは、範囲内の各要素が識別子i
によってブロック内に表されることを意味します。 -
puts
はRubyの出力メソッドで、印刷するたびに自動改行があります。 (自動改行をしたくない場合はprint
を使うことができます) -
i.even?
i
が偶数であるかどうかを調べます。i % 2 == 0
も使用できました。ただし、組み込みメソッドを使用することが望ましいです。 -
? "even" : "odd"
これはルビの三項演算子です。三項演算子の構築方法はexpression ? a : b
。これは
if expression a else b end
-
1行より長いコードの場合、 block
はmultiline block
として渡されmultiline block
。
方法2:複数行
(1..10).each do |i| if i.even? puts 'even' else puts 'odd' end end
multiline block
は、 do
は開始ブラケットを置き換え、 end
はinline
スタイルの終了ブラケットを置き換えます。
Rubyはreverse_eachもサポートしています。配列を逆方向に繰り返します。
@arr = [1,2,3,4]
puts @arr.inspect # output is [1,2,3,4]
print "Reversed array elements["
@arr.reverse_each do |val|
print " #{val} " # output is 4 3 2 1
end
print "]\n"
クラス内での実装
Enumerable
はRubyで最も人気のあるモジュールです。その目的は、 map
、 select
、 reduce
などの反復可能なメソッドを提供することです。Enumerableを使用するクラスには、 Array
、 Hash
、 Range
含まれEnumerable
。これを使用するにinclude Enumerable
をinclude Enumerable
しinclude Enumerable
each
を実装する必要がinclude Enumerable
。
class NaturalNumbers
include Enumerable
def initialize(upper_limit)
@upper_limit = upper_limit
end
def each(&block)
0.upto(@upper_limit).each(&block)
end
end
n = NaturalNumbers.new(6)
n.reduce(:+) # => 21
n.select(&:even?) # => [0, 2, 4, 6]
n.map { |number| number ** 2 } # => [0, 1, 4, 9, 16, 25, 36]
地図
変更されたオブジェクトを返しますが、元のオブジェクトはそのまま残ります。例えば:
arr = [1, 2, 3]
arr.map { |i| i + 1 } # => [2, 3, 4]
arr # => [1, 2, 3]
map!
元のオブジェクトを変更します。
arr = [1, 2, 3]
arr.map! { |i| i + 1 } # => [2, 3, 4]
arr # => [2, 3, 4]
注: collect
を使用して同じことを行うこともできます。
複雑なオブジェクトを反復する
配列
ネストされた配列を反復処理できます。
[[1, 2], [3, 4]].each { |(a, b)| p "a: #{ a }", "b: #{ b }" }
次の構文も使用できます。
[[1, 2], [3, 4]].each { |a, b| "a: #{ a }", "b: #{ b }" }
生産する:
"a: 1"
"b: 2"
"a: 3"
"b: 4"
ハッシュ
キーと値のペアを反復処理できます。
{a: 1, b: 2, c: 3}.each { |pair| p "pair: #{ pair }" }
生産する:
"pair: [:a, 1]"
"pair: [:b, 2]"
"pair: [:c, 3]"
キーと値を同時に反復処理することができます:
{a: 1, b: 2, c: 3}.each { |(k, v)| p "k: #{ k }", "v: #{ k }" }
生産する:
"k: a"
"v: a"
"k: b"
"v: b"
"k: c"
"v: c"
イテレータの場合
これは4から13までを繰り返します(これを含む)。
for i in 4..13
puts "this is #{i}.th number"
end
また、forを使って配列を繰り返し処理することもできます
names = ['Siva', 'Charan', 'Naresh', 'Manish']
for name in names
puts name
end
インデックスによる反復
時には、列挙子を反復処理しながら現在の要素の位置( インデックス )を知りたいことがあります。そのために、Rubyはwith_index
メソッドを提供しています。すべての列挙子に適用できます。基本的には、列挙にwith_index
を追加することによって、その列挙を列挙することができます。インデックスは第2引数としてブロックに渡されます。
[2,3,4].map.with_index { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 0 => 2
#Element of array number 1 => 3
#Element of array number 2 => 4
#=> [nil, nil, nil]
with_index
にはオプションの引数があります。最初のインデックスはデフォルトで0
です。
[2,3,4].map.with_index(1) { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 1 => 2
#Element of array number 2 => 3
#Element of array number 3 => 4
#=> [nil, nil, nil]
特定のメソッドeach_with_index
ます。 each.with_index
の唯一の違いは、引数を渡すことができないため、最初のインデックスは常に0
です。
[2,3,4].each_with_index { |e, i| puts "Element of array number #{i} => #{e}" }
#Element of array number 0 => 2
#Element of array number 1 => 3
#Element of array number 2 => 4
#=> [2, 3, 4]