Ruby いろんなループ(トリッキーなもの含む)
ループと言いつつ、やっているのは1から10の整数の乱数を作って、そこから6以上の値はもう一度やり直す。というもの
言い換えると、途中脱出が可能な無限ループ
です。え?スタックオーバーフロー?・・・
多分、最初のと最後(2018年11月24日追記分)がいいと思います。はい
puts "loopを使ったもの。多分これが一番メジャー" a = loop{ n = rand(1..10) break n if n<=5 } p a puts "再帰を使ったもの" def f n = rand(1..10) return f if n>5 n end a = f p a puts "ラムダ式を使ったもの。関数使ったやつとほぼ同じ" f = ->{ n = rand(1..10) (n<=5)? n : f.call } a = f.call p a puts "ただのwhile。他言語ならdo-whileを使う" a = nil while a.nil? || a>5 a = rand(1..10) end p a puts "whileとbreakを使ったもの" a = while true n = rand(1..10) break n if n<=5 end p a puts "例外のretryを使ったもの。速度的にも例外的にもあまり良くない気がする" a = begin n = rand(1..10) raise if n>5 n rescue retry end p a puts "いい感じのやつを自分で定義したもの" def loop1 yield end a = loop1{ n = rand(1..10) redo if n>5 n } p a puts "Integer#timesを使ったもの。" a = nil 1.times{ n = rand(1..10) if n>5 redo else a = n end } p a puts "Enumerable#mapを使ったもの。eachとかでもできるよね" a = [nil].map{ n = rand(1..10) redo if n>5 n }.first p a puts "無限リストを使ったもの。loop使ってるじゃんとか言わないで。selectで表現できるのは加点" a = Enumerator.new{|y|loop{y<<rand(1..10)}} .lazy .select{|n|n<=5} .first p a puts "関数に囲ってきれいに書けるようにしたもの" def infinite_list Enumerator.new{|y|loop{y<<yield}}.lazy end a = infinite_list{rand(1..10)} .select{|n|n<=5} .first p a # 2017年11月21日追加 puts "Rangeからの無限リスト" a = (1..Float::INFINITY) # 1/0.0で無限が作れるので、そっちでもいいのかも .lazy .map{|_|rand(1..10)} .select{|n|n<=5} .first p a puts "デフォルト引数を使ったもの" def f n=(n=rand(1..10);(n>5)? f : n) n end a = f() p a # 2018年11月24日追加 puts "loop+lazy+with_index 一年間の成長が詰まってる感じがする" a = loop .lazy .map{rand(1..10)} .select{|n|n<=5} .first p a
JavaScriptならイベントを使う方法があるらしい。