繰り返し処理

Ruby ハッシュ値をeachで繰り返し処理してみよう

Rubyのハッシュ値のeachでの繰り返し処理について。

2通りの使い方があるのでご紹介致します。

まずは、ハッシュ値からkeyとvalueを取得するパターンです。

capitals = {
  'Japan'          => 'Tokyo', 
  'UnitedKingdom'  => 'London', 
  'Netherlands'    => 'Amsterdam', 
  'France'         => 'Paris'
}
# ここはおまけ
p capitals['UnitedKingdom'] # => "London"
p capitals['Switzerland']   # => nil (値がない場合)

capitals.each do |key, value|
  puts "国は#{key}です。首都は#{value}です"
end
# => 国はJapanです。首都はTokyoです
# => 国はUnitedKingdomです。首都はLondonです
# => 国はNetherlandsです。首都はAmsterdamです
# => 国はFranceです。首都はParisです

今回はサンプルなので、keyとvalueという名前にしていますが
countryとcapitalとかにしたほうが可読性は上がるかもしれませんね。

次は配列として処理をする場合です。
配列の0番目にkey、1番目にvalueが入ります。

capitals.each do |capital|
  puts "国は#{capital[0]}です。首都は#{capital[1]}です"
end
# => 国はJapanです。首都はTokyoです
# => 国はUnitedKingdomです。首都はLondonです
# => 国はNetherlandsです。首都はAmsterdamです
# => 国はFranceです。首都はParisです

どうでしょうか???

配列のアクセスが少し面倒な感じですね。笑

自分で実装する場合は前者のほうがいいと思います(*^^*)

 

何かの参考になれば幸いです(*^^*)

Ruby 繰り返し処理をやり直したいときに使えるredo

Rubyの便利な書き方だなと思って記事にしました。

 

まずは、行ったことがありますか?の回答に「ある」となるまで処理を繰り返します。

areas = ['東京', '北海道', '沖縄']
areas.each do |area|
  # sampleでランダムに選択
  answer = ['ある', 'ない'].sample
  puts "#{area}に行ったことありますか?#{answer}"
  redo unless answer == 'ある'
end
# => 東京に行ったことありますか?ない
# => 東京に行ったことありますか?ない
# => 東京に行ったことありますか?ない
# => 東京に行ったことありますか?ある ★次に行く
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ある ★次に行く
# => 沖縄に行ったことありますか?ある ★次に行く

「ある」となったときに次のareaに移っていますね。

次に上記の書き方だと永遠と続く可能性もあります。
回数制限を設けたのが以下の例になります。

areas = ['東京', '北海道', '沖縄']
count = 0
areas.each do |area|
  count += 1
  answer = 'ない'
  puts "#{area}に行ったことありますか?#{answer}"
  redo if answer != 'ある' && count < 2 count = 0 end # => 東京に行ったことありますか?ない
# => 東京に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 北海道に行ったことありますか?ない
# => 沖縄に行ったことありますか?ない
# => 沖縄に行ったことありますか?ない

「ある」とあるまで処理をやり直すのですが2回未満までとなっているので

2回ずつ処理をして終わっていますね。

 

何か参考になれば幸いです(*^^*)

Rubyのeach, for, whileなどの繰り返し処理の外にbreakできない時の対処法

Rubyで二重でeach,forなどの繰り返し処理をしてbreakで抜けようとすると

外に抜けれない状態になります。

その時の対処方法について。

 

まずは、二重でeachを使った時の処理結果は以下の通りです。

areas = ['東京','埼玉','千葉','茨城']
nums = [1,2,3,4]

areas.each do |area|
    nums.shuffle.each do |num|
        # area文字列, 3 になったらbreak
        puts "#{area}, #{num}"
        break if num == 3
    end
end
# 結果
# 東京, 2
# 東京, 1
# 東京, 3 <- ここ
# 埼玉, 2
# 埼玉, 1
# 埼玉, 3 <- ここ
# 千葉, 4
# 千葉, 1
# 千葉, 3 <- ここ
# 茨城, 1
# 茨城, 3 <- ここ

3のときに次のareasに移って処理を繰り返していますね。

これを1回目の3で処理を終わらせたい場合は
catch :XXXX(適当な名前) と throw :XXXX(適当な名前)を使いましょう!

catch :done do
    areas.each do |area|
        nums.shuffle.each do |num|
            puts "#{area}, #{num}"
            if num == 3
                throw :done
            end
        end
    end
end
# 結果
# 東京, 1
# 東京, 4
# 東京, 3

注意点は、catchとthrowのあとに付ける名前は一致させることです。

違うとエラーになるので注意しましょう。

 

繰り返し処理を一気に全部抜けたいんだ!という方はぜひ参考にしてみてください(*^^*)