コード:
c = 0
items.each { |i|
puts i.to_s
# if c > 9 escape the each iteration early - and do not repeat
c++
}
最初の10個のアイテムを取得してから、「各」ループを終了します。
コメント行を何に置き換えますか?より良いアプローチはありますか?もっとRuby慣用句?
コード:
c = 0
items.each { |i|
puts i.to_s
# if c > 9 escape the each iteration early - and do not repeat
c++
}
最初の10個のアイテムを取得してから、「各」ループを終了します。
コメント行を何に置き換えますか?より良いアプローチはありますか?もっとRuby慣用句?
解決策はbreak
機能しますが、より機能的なアプローチがこの問題に本当に適していると思います。take
最初の10個の要素を印刷して印刷したいので、試してみてください
items.take(10).each { |i| puts i.to_s }
++
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
break
ループから早期に脱出するために機能しますが、それを行うだけの方が慣用的ですitems[0..9].each {|i| puts i}
。(そして、あなたがしているのが文字通り何も変更せずにアイテムを印刷することだけであるなら、あなたはただすることができますputs items[0..9]
。)
別のバリアント:
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
など。)
別のオプションは
items.first(10).each do |i|
puts i.to_s
end
これは、イテレータを壊すよりも少し簡単に読み取れます。最初に、十分な数がない場合は、利用可能な数のアイテムのみが返されます。
これはあなたが望むもののように見えますか?
10.times { |i|
puts items[i].to_s
}
items.each_with_index { |i, c| puts i and break if c <= 9 }
それは尋ねられました:
最初の10個のアイテムを取得してから、「各」ループを終了します。
を使用throw
しcatch
てこれを実現しますが、例にほとんど変更を加えません。
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
ラベルだけが返されます。:done
collected
catch
:done
collected
そして、これを少し「ルビー」するために:
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個未満の場合は戻ります。reduce
inject([])
item
inject
collected
ほとんどの回答は、質問されたものではなく、質問の意図である可能性があるものに答えようとしており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