Rubyの自動カウンターはそれぞれですか?


134

for-eachとカウンターを使用したい:

i=0
for blah in blahs
    puts i.to_s + " " + blah
    i+=1
end

それを行うより良い方法はありますか?

注:blahs配列とハッシュのどちらであるかはわかりませんが、実行blahs[i]しなくてもそれほど魅力的ではありません。またi++、Rubyでの記述方法も教えてください。


技術的には、MattとSqueegyの答えが最初に出てきましたが、私はparadojaに最良の答えを出しています。また、彼の答えにはバージョンに関するメモがありましたが、これはまだ関連があります(私のUbuntu 8.04がRuby 1.8.6を使用している限り)。


使用していたはずですputs "#{i} #{blah}"たくさんより簡潔です。


Rubyにはインクリメント演算子はありません。あなたが書いたn + = 1は、最も近いものです。それはn + = 1の構文糖である必要があり、それ自体がn = n + 1の省略形です。++のアイデアは、変数を再割り当てしているという事実を隠すため拒否されました。rubyurl.com/Dsb1
チャック

いいね!チャックありがとう。私はJavaで++ iとi ++を学ぶことを余儀なくされたので、いつもそこにあると思っていました。
Dan Rosenstark、2009

回答:


190

人々が言っ​​たように、あなたは使うことができます

each_with_index

しかし、 "each"とは異なるイテレータを使用してインデックスが必要な場合(たとえば、インデックスなどにマップする場合)、列挙子をeach_with_indexメソッドで連結するか、単にwith_indexを使用できます。

blahs.each_with_index.map { |blah, index| something(blah, index)}

blahs.map.with_index { |blah, index| something(blah, index) }

これは、ruby 1.8.7と1.9からできることです。


1
これは1.9の新機能であることは注目に値します。
Zach Langley、

1
よく見つかりました。実際には、1.8.7にも含まれていますが、追加する価値があります。
paradoja

Ubuntuにすべてをインストールしたのに、なぜRuby 1.8.6を使用しているのですか?1.8.7は実験的/ベータですか?
Dan Rosenstark、2009

どのUbuntuを使用していますか?Intrepidには1.8.7があります。これが最後の安定版です(ruby-lang.org/en/downloads)。ただし、同じ動作をするためにmonkeypatch ruby​​ 1.8.6を使用できます(strictlyuntyped.com/2008/09/ruby-187s-enumerator-class.htmlを参照)。
パラドハ2009

3
ディストリビューションが遅れていることにうんざりしていたので、UvmとLinux MintでのRubyインストールの管理にrvmを使い始めました。
Tin Man

55
[:a, :b, :c].each_with_index do |item, i|
  puts "index: #{i}, item: #{item}"
end

これをforで行うことはできません。とにかく、私はたいてい、個人的にそれぞれに宣言的な呼びかけをするのが好きです。for構文の制限に達したときに他のフォームに簡単に移行できるためです。


いいですね、for構文の制限に関するポイントがわかります。複数のパラメーターを持つブロックに慣れる必要があります。
Dan Rosenstark、2009

11

はい、それcollection.eachはループを行うことです、そしてeach_with_indexから、インデックスを取得します。

これは基本的なRubyであるため、おそらくRubyの本を読むべきです。知らなければ、大きな問題を抱えることになります(試してみてください: http://poignantguide.net/ruby/参照して)。

Rubyのソースコードから取得:

 hash = Hash.new
 %w(cat dog wombat).each_with_index {|item, index|
   hash[item] = index
 }
 hash   #=> {"cat"=>0, "wombat"=>2, "dog"=>1}

問題ありません。喜んでお手伝いします。.eachブロックについて「平均的」であるという意味ではありませんでした。これらは基本的なルビー構造であり、その場でそれらを学習することは本当に非常に苦痛です。:)弾丸を噛んで、数時間かけて読むのがベストです!
マットRogish 2009

6

新しいバージョンのがない場合はeach_with_index、このzipメソッドを使用して、インデックスと要素をペアにすることができます。

blahs = %w{one two three four five}
puts (1..blahs.length).zip(blahs).map{|pair|'%s %s' % pair}

生成されるもの:

1 one
2 two
3 three
4 four
5 five

1
'%s %s' % [1, "two"]Rubyのドキュメントであなたの答えからこのコードをどこで見つけることができますか?圧縮とマッピングに1行を使用して、垂直方向のスペースを節約していただきありがとうございます。
Dan Rosenstark、

1
このコンテキストでは、%記号演算子はStringクラスのメソッドです。ruby-doc.org/core/classes/String.html#M000770でそれについて読むことができます。または、コマンドプロンプトでri String#%と入力することもできます。または、ri%と入力して、それを認識する文書化されたすべてのクラスを表示することもできます。
ジョージ

4

することについてのあなたの質問に関してはi++、まあ、Rubyではそれを行うことはできません。i += 1あなたが持っていた文は、あなたがそれを行うことになっている正確にどのようにあります。



1

blahsがEnumerableで混在するクラスである場合、これを実行できるはずです。

blahs.each_with_index do |blah, i|
  puts("#{i} #{blah}")
end

1

それぞれのルビのインデックスを取得したい場合は、使用できます

.each_with_index

これがどのように.each_with_index機能するかを示す例です:

range = ('a'..'z').to_a
length = range.length - 1
range.each_with_index do |letter, index|
    print letter + " "
    if index == length
        puts "You are at last item"
    end
end

これは印刷されます:

a b c d e f g h i j k l m n o p q r s t u v w x y z You are at last item
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.