Nobody dies a virgin

映画/音楽/時々プログラミング

文字列置換の備忘録

受け取った文字列を一括置換してくれる書き方

文字列変換で便利な記法があったのでメモ。 以下元となる文字列から変換したい文字があったとする。 "FRTDCABC" => "FRTD3123"

before after
A 1
B 2
C 3
s="FRTDCABC"
puts s.gsub(/[AEGIOSZ]/, "A" => "1", "B" => "2", "C" => "3")

 => FRTD3123

このように記述すれば変換した文字列が表示される。

配列の要素の足し算(inject)

これまた備忘録になります。 配列の足し算をするときに毎回、eachメソッドを使って要素を一つずつ取得して足し算していく書き方がなんとなく嫌だったので別の方法を探していたところinjectメソッドというものを発見した。

enum.inject {|memo, item| block }

enum: (例えば)配列やハッシュ memo: ブロックの中で有効な変数 item: 配列やハッシュから取り出してきた値を格納する変数

s = [1, 2, 3]
p s.inject(0){ |sum, i| sum + i}

=> 6

まずブロック内で有効な変数sumに0を代入する部分が

inject(0)

そして、iの部分では配列から値を順々に取り出している。 以下はブロックの処理の部分。

sum + i

inject(0)初期化で初期化を行わないとブロックが実行される回数が異なるので注意。

p [1,2,3].inject{|sum, i| sum + i*i }
=> 14

p [3,2,1].inject{|sum, i| sum + i*i }
=> 8

これは平方和を求めるプログラム。各要素の二乗を足し合わせている。 なぜ上と下のコードの結果が異なるかというと、ブロックの中で格納される変数が異なるからである。

上では

1回目: 1 + 2*2 =5(sum = 1, i = 2)

2回目: 5+3*3 = 14(sum = 5, i = 3)

下では

1回目: 3+2*2= 7(sum = 3, i = 2)

2回目: 7+1*1 = 8(sum = 7, i =1)

こういうことを防ぐために、一回目のブロック実行時のsumに0が入るように初期化する。

[n..m].inject(0){ |sum, i| block }

参考URL: Rubyのinjectには初期値を明示的に指定したほうがいい