はじめに
駆け出しエンジニアの私が、AtCoderやpaizaでアルゴリズム問題を解いていく中で、とても便利だったメソッドを書き残す。
puts, p, printの違い
自分の言葉で説明しようと思ったが、web上に山ほど記事があったので、止めることにする。
【Ruby超入門】print、puts、pの違い
https://yukimasablog.com/ruby-print-puts-p
【Ruby】p, puts, printメソッドの違い
https://qiita.com/rkkmshde/items/daf75aca9675f5a01d17
デバッグの時に使いこなせると、複雑なコードを書く時にかなり効率よくエラーやその原因に気づける。
三項演算子
if 〜 else 〜 end
をもっと効率よく書くことができる。
number = 24
if number.even?
n = "偶数"
else
n = "奇数"
end
puts n
# => 偶数
この処理が、、、
number = 24
n = number.even? ? "偶数" : "奇数"
puts n
# => 偶数
こうなる。
条件 ? (条件がtrueだった時の処理) : (条件がfalseだった時の処理)
という構造だ。
map
# 入力値
# 12 30 40
input = gets.split.map(&:to_i)
# 出力値
# [12, 30, 40]
# という風な配列になる。
入力値の数値や文字列を一つ一つの要素に分けて配列にしたい時に使うことができる。
**"&:"**メソッドの説明については、今回は割愛させていただく。
詳しくは、
https://qiita.com/soma_sekimoto/items/a828b8f88b78aac2e7df
こちらの記事を参考に。
any? と all? と one?
繰り返し処理を使って条件を満たしているかどうかを確かめたい時に、これらのメソッドがとても役に立つ。
これを知らなかった頃は、全てeachで代用しようとしていたので、コードがとんでもないことになってしまっていた。
array = [30, 14, 23, 15]
array.any? {|num| num % 7 == 0} # 7で割り切れる要素(14)がある
# => true
any?: 各要素の中で、1つでも条件に合うものがあればtrueを返す。
all?: 全ての要素が条件に合えばtrueを返す。
one?: 各要素の中で、条件に合うものが一つだけであればtrueを返す。
reduce
(1..10).reduce(5) {|a, n| a + n}
# => 5 + 1 = 6, この6が次の処理のaとなる。
# つまり、2回目の処理は、6 + 2となる。
# 処理結果 => 60
reduceメソッドでは、ブロック処理内の引数を2つ(aとn)設定する。
aは初期値(ここでは5)、nは各要素(ここでは、1から10の整数)になる。
between?
23.between?(0, 30)
# => true
'G'.between?('A', 'F')
# => false
指定した値(ここでは、23 と 'G')が範囲内(0〜30 と A〜F)に入っているかどうかを判断するメソッド
index
array = ["ruby", "java", "php"]
p array.index("java")
# => 1
# "java"のindex番号が返される。
transpose
配列に要素として他の配列が格納されている場合に、配列を行列と見なし、行と列を入れ替えるメソッド
array = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
p array.transpose
# => [[1,5,9], [2,6,10], [3,7,11], [4,8,12]]
行と列の考え方を使うアルゴリズム問題でとても活躍してくれた。
chars
greeting = "hello"
p greeting.chars
# => ["h", "e", "l", "l", "o"]
上記のように、文字列を1文字ずつに分割して配列として返す。
また、こういう書き方もできる。
num = "19800".chars.map(&:to_i)
p num
# => [1, 9, 8, 0, 0]
桁ごとの数字を処理したい時などに使える。
zip
複数の配列を同時に処理したい時は、このzipメソッドが便利だ。
number = [1, 2, 3, 4, 5]
alphabet = ["a", "b", "c", "d", "e"]
p number.zip(alphabet)
number.zip(alphabet) do |num, alpha|
p num
p alpha
end
# => [[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"]]
# => 1
# => "a"
# => 2
# => "b"
...
# => 5
# => "e"
上記のように、配列として返すこともできるし、複数の配列にeachメソッドを用いたような処理の仕方もできる。
select, reject
select: {}ブロック内の式がtrueになる要素だけを抽出する。
reject: {}ブロック内の式がfalseになる要素だけを抽出する。
p [1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 }
p [1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 }
# => [2, 4, 6]
# => [1, 3, 5]
おわりに
rubyは他の言語と比べると、メソッドの数が多いので、直感的なコードが書けることに気がつき、さらにrubyが好きになった。
皆さんもぜひ、rubyを用いてアルゴリズムを書く際は、参考にしてもらいたい。