[1,2,3,4,5,6,7].delete_if{|i| i < 4 }
たとえば、上記では、なぜ|i|
前にを付ける必要があるのi < 4
でしょうか?
私は Ruby プログラミングに慣れていないので、この要素の目的が理解できません。
これは、ブロックの非常に基本的な Ruby 構文です。ブロックは、バーの間に指定されたパラメーターを取る場合があります|
。あなたの場合:
[1,2,3,4,5,6,7].delete_if { |i| i < 4 }
このdelete_if
型のメソッドArray
は、ブロックをパラメーターとして受け入れます。ブロックが指定されると、ブロックは配列要素をパラメーターとして受け入れます。したがってi
、この場合、配列内の各値を反復処理します。より具体的には、要素が の場合、その要素は配列から削除され< 4
ます。結果は次のようになります。
[4,5,6,7]
Ruby 型のメソッドのドキュメントをよく目にします。たとえば、次のように書かれています。
delete_if { |item| block } -> Array
これは、メソッドがパラメーターを持つブロックを受け入れることを意味します。block
これは、パラメーターを使用するコードであり、出力は別の配列です。メソッドの説明では、ドキュメント ( Ruby Arrayなど)でより詳細に説明しています。
Ruby の入門情報をオンラインで読むか、これについて詳しく説明している入門書を読むことをお勧めします。
ここに最初の行i
を入れるのと同じ理由で、そこに入れる必要があります。i
def plus_one(i)
return i + 1
end
メソッドの引数に名前を付ける必要があります。これは、後でメソッドのローカル変数として使用します。
Ruby ブロックはメソッドに似ており、引数を受け取ることもできます。また、それらを宣言するための構文は少し異なります: で囲みます| |
。
OPの質問にはすでに回答がありますが、回答をやり直しました。これは、同じ質問を持つ将来のSOユーザーに役立つ可能性のあるこれを説明する新しい方法を考えたからです。
高校の代数から、次のような関数を覚えておく必要がありますf(x) = x + 1
。
の周りに中かっこを置くことを想像してくださいx + 1
:f(x) = { x + 1 }
次に(x)
、中括弧内に to を移動します。f = {(x) x + 1 }
f
そして、名前:を取り除きます{(x) x + 1 }
。これにより、「無名関数」、つまり「ラムダ」になります。
ここに問題があります: 中括弧には、それ自体が括弧を使用する可能性のある任意のステートメントを含めることができます: (x + 1) * 4
. (x)
では、Rubyは が関数の引数であって、実行する式ではないことをどうやって知るのでしょうか? 他の構文を使用する必要がありました。したがって、縦棒: |x|
. (少なくとも、それが思考プロセスだったと思います)。
名前がなく、事前に定義されていないことを除いて、{|i| i > 4 }
は と同じですf(i) = i > 4
。そのため、パラメーターは、名前の外部に付けられるのではなく、関数自体の「内部」で定義する必要があります。
Array#delete_if
はそのような関数 (このように使用される場合は「ブロック」と呼ばれます) を期待し、それをどうするかを知っています。配列の各メンバーを[1,2,3,4,5,6,7]
引数としてブロックに渡し、そのメンバーが truei
かどうかを確認します。i > 4
これは、次のようなことをするのと同じです:
def greater_than_four(x)
x > 4
end
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if greater_than_four(el)
end
greater_than_four
次のようにオンザフライでラムダを定義することにより、事前にメソッドを定義することを避けることができます。
arr = [1,2,3,4,5,6,7]
arr.each do |el|
arr.delete(el) if lambda{|i| i > 4}.call(el)
end
しかし、Array#delete_if
すでにブロックを想定しており、各要素でそれを呼び出すことを既に知っているため、大量のコードを節約できます。
[1,2,3,4,5,6,7].delete_if{|i| i < 4 }