42

コード:

 c = 0  
 items.each { |i|  
   puts i.to_s    
   # if c > 9 escape the each iteration early - and do not repeat  
   c++  
 }  

最初の10個のアイテムを取得してから、「各」ループを終了します。

コメント行を何に置き換えますか?より良いアプローチはありますか?もっとRuby慣用句?

4

8 に答える 8

61

解決策はbreak機能しますが、より機能的なアプローチがこの問題に本当に適していると思います。take最初の10個の要素を印刷して印刷したいので、試してみてください

items.take(10).each { |i| puts i.to_s }
于 2009-10-14T19:26:42.713 に答える
51

++Rubyには演算子はありません。doまた、end複数行のブロックを使用することも慣例です。ソリューションを変更すると、次のようになります。

c = 0  
items.each do |i|  
  puts i.to_s    
  break if c > 9
  c += 1 
end

またはまた:

items.each_with_index do |i, c|  
  puts i.to_s    
  break if c > 9
end

Ruby Break、Redo、およびNextのプログラミングeach_with_indexも参照してください。

更新:範囲を使用した チャックの回答はRubyに似ており、nimrodmを使用した回答takeはさらに優れています。

于 2009-10-14T19:04:59.067 に答える
7

breakループから早期に脱出するために機能しますが、それを行うだけの方が慣用的ですitems[0..9].each {|i| puts i}。(そして、あなたがしているのが文字通り何も変更せずにアイテムを印刷することだけであるなら、あなたはただすることができますputs items[0..9]。)

于 2009-10-14T19:24:50.540 に答える
4

別のバリアント:

puts items.first(10)

これは、10項目未満の配列で正常に機能することに注意してください。

>> nums = (1..5).to_a
=> [1, 2, 3, 4, 5]
>> puts nums.first(10)
1
2
3
4
5

(もう1つの注意点として、多くの人が何らかの形を提供していますputs i.to_sが、そのような場合、.to_s冗長ではありませんか?puts自動的.to_sに非文字列を呼び出して印刷します。必要なのは必要な.to_s場合のみです。言うputs 'A' + i.to_sなど。)

于 2009-10-14T19:34:46.910 に答える
4

別のオプションは

items.first(10).each do |i|
  puts i.to_s
end

これは、イテレータを壊すよりも少し簡単に読み取れます。最初に、十分な数がない場合は、利用可能な数のアイテムのみが返されます。

于 2009-10-14T19:36:32.383 に答える
1

これはあなたが望むもののように見えますか?

10.times { |i|
  puts items[i].to_s
}
于 2009-10-14T19:02:36.017 に答える
0
items.each_with_index { |i, c| puts i and break if c <= 9 }
于 2009-10-14T19:15:15.087 に答える
-1

それは尋ねられました:

最初の10個のアイテムを取得してから、「各」ループを終了します。

を使用throwcatchてこれを実現しますが、例にほとんど変更を加えません。

catch(:done) do
    c = 0
    collected = []
    items.each do |item|
        collected << item
        throw(:done, collected) if c == 9 # started at 0
        c += 1
    end
    collected # if the list is less than 10 long, return what was collected
end

とを待っているthrowラベルだけが返されます。:donecollectedcatch:donecollected

そして、これを少し「ルビー」するために:

catch(:done) do
    items.inject([]) do |collected, item|
        throw(:done, collected) if collected.size == 10
        collected << item # collected gets returned here and populates the first argument of this block
    end
end

与えられた空の配列にsが注入されているのに、なぜ一部の人が代わりに使用して使用することを拒否するのかinject(それらは同等です)はわかりません!とにかく、アイテムが10個未満の場合は戻ります。reduceinject([])iteminjectcollected

ほとんどの回答は、質問されたものではなく、質問の意図である可能性があるものに答えようとしておりitems.take(10)、その場合は完全に理にかなっています。しかし、100ドルの予算内に収まる最初のアイテムを手に入れたいと想像することができます。次に、簡単に次のことができます。

catch(:done) do
    items.inject({items: [], budget: 100}) do |ledger, item|
        remainder = ledger[:budget] - item.price
        if remainder < 0
            throw(:done, ledger)
        else
            ledger.tap do |this|
                this[:items] << item
                this[:budget] = remainder
            end # tap just returns what is being tapped into, in this case, ledger
        end
    end
end
于 2017-01-21T14:18:46.123 に答える