each

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のあとに付ける名前は一致させることです。

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

 

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

Rubyのeachでパラメータが参照できない?!forとの違い

似ているようで微妙違うeachとfor

似ているようで少し違うrubyのeachとforの例をご紹介したいと思います。

nums = [1,2,3,4]
sum = 0
for n in nums
    sum += n
end
puts sum # sum => 10
puts n   # n => 4 ※参照できてるのがポイント!!

for文で使われてるnがforの外でも参照出来ているのがポイントです!

nums = [1,2,3,4]
sum = 0
nums.each do |a|
    sum += a
end
puts sum # sum => 10
puts a   # ERROR!!!!

each文で定義されたaはeachの外では参照できないんですね。

同じような処理でも小さな違いがありますね。

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

Rubyの多重配列とeach

Rubyで多重配列とeachを組み合わせて使ってみる

Rubyの多重配列でeachを使うととても簡単に処理ができます。

各面積を算出するサンプルコードを書いてみました。

hw = [
  [10, 20],
  [30, 40],
  [50, 20]
]

num = []
hw.each do |length, width|
  # 面積
  num << length * width end # num => [200, 1200, 1000]

PHPメインで使っていたため、こんな簡単にかけるんだと衝撃でした。
PHPだと以下のような感じですね。

$hw = [
  [10, 20],
  [30, 40],
  [50, 20],
];

$num = [];
foreach ($hw as $nums) {
  // 面積
  $num[] = $nums[0] * $nums[1];
}
// num=>[200, 1200, 1000]

Rubyだとすぐ変数に入れることができて、変数名で明示的にわかるので可読性が上がりますね!
参考になれば幸いです。