Array
->|value,index|
とHash
->が正気ではないと言っているので|key,value|
はありませんが(Horace Loebのコメントを参照)、この取り決めを期待する正気の方法があると言っています。
配列を扱うときは、配列内の要素に焦点を合わせます(インデックスは一時的なものであるため、インデックスではありません)。メソッドはそれぞれインデックス付きです。つまり、each + index、または| each、index |、または|value,index|
。これは、インデックスがオプションの引数として表示されていることとも一致しています(例:| value |)。| value、index =nil|と同等です これは|value、index|と一致しています。
ハッシュを処理するときは、値よりもキーに重点を置くことが多く、通常はキーと値をまたはのいずれかの順序で処理しkey => value
ますhash[key] = value
。
ダックタイピングが必要な場合は、Brent Longboroughが示したように定義されたメソッドを明示的に使用するか、maxhawkinsが示したように暗黙的なメソッドを使用します。
Rubyは、プログラマーが言語に合わせて調整することではなく、プログラマーに合わせて言語を調整することを目的としています。これが非常に多くの方法がある理由です。何かについて考える方法はたくさんあります。Rubyでは、最も近いものを選択すると、コードの残りの部分は通常、非常にきれいかつ簡潔になります。
「Rubyで配列を反復処理する「正しい」方法は何ですか?」という元の質問については、コアな方法(つまり、強力な構文糖衣構文やオブジェクト指向の力がない場合)は次のことを行うことだと思います。
for index in 0 ... array.size
puts "array[#{index}] = #{array[index].inspect}"
end
しかし、Rubyはすべて強力なシンタックスシュガーとオブジェクト指向のパワーに関するものですが、とにかくここではハッシュと同等であり、キーを注文することも注文しないこともできます。
for key in hash.keys.sort
puts "hash[#{key.inspect}] = #{hash[key].inspect}"
end
したがって、私の答えは、「Rubyで配列を反復処理する「正しい」方法は、ユーザー(つまり、プログラマーまたはプログラミングチーム)とプロジェクトによって異なります。」です。より優れたRubyプログラマーは、より優れた選択を行います(どの構文能力および/またはどのオブジェクト指向アプローチか)。優れたRubyプログラマーは、さらに多くの方法を探し続けています。
ここで、別の質問をしたいと思います。「Rubyの範囲を逆方向に反復する「正しい」方法は何ですか?」(この質問は、私がこのページにたどり着いた方法です。)
(フォワードのために)行うのはいいことです:
(1..10).each{|i| puts "i=#{i}" }
しかし、私は(後方のために)するのが好きではありません:
(1..10).to_a.reverse.each{|i| puts "i=#{i}" }
ええと、私は実際にはそれをやりすぎてもかまいませんが、逆方向に教えるときは、生徒に良い対称性を示したいと思います(つまり、最小の違いで、たとえば逆を追加するか、ステップ-1を追加するだけですが、他のものを変更する)。あなたができること(対称性のために):
(a=*1..10).each{|i| puts "i=#{i}" }
と
(a=*1..10).reverse.each{|i| puts "i=#{i}" }
あまり好きではありませんが、できません
(*1..10).each{|i| puts "i=#{i}" }
(*1..10).reverse.each{|i| puts "i=#{i}" }
#
(1..10).step(1){|i| puts "i=#{i}" }
(1..10).step(-1){|i| puts "i=#{i}" }
#
(1..10).each{|i| puts "i=#{i}" }
(10..1).each{|i| puts "i=#{i}" } # I don't want this though. It's dangerous
あなたは最終的にすることができます
class Range
def each_reverse(&block)
self.to_a.reverse.each(&block)
end
end
しかし、私はオブジェクト指向のアプローチではなく、純粋なRubyを教えたいと思っています(まだ)。逆方向に繰り返したい:
- 配列を作成せずに(0..1000000000を考慮)
- 任意の範囲で機能します(整数だけでなく文字列など)
- 余分なオブジェクト指向の力を使用せずに(つまり、クラスの変更なし)
これは、メソッドを定義しないと不可能だと思いますpred
。つまり、それを使用するようにRangeクラスを変更する必要があります。これができる場合はお知らせください。そうでない場合は、残念ながら不可能の確認をお願いします。おそらくRuby1.9はこれに対処しています。
(これを読んでくれてありがとう。)