【ruby】rubyでよく使うメソッドまとめ その3

よく使うメソッド

実業務でもたまに使うけど、どっちかっていうとAtCorderの問題でよく使うやつをまとめておく。
今までのまとめはこちら

yasagori-programing.hatenablog.jp

文字の出現回数を数えたい

countメソッド

文字列の中から特定の文字をの出現回数を数えるなら'count'メソッドで十分。

s = 'hogehoge'
p s.count('h')
=> 2

じゃあ文字列もってやるとおかしなことになる。

s = 'hogehoge'
p s.count('hoge')
=> 8   # 絶対違う

そんな時はscanメソッドを使う。

scanメソッド

文字列の中から特定の文字列を抽出し、その配列を返す。
返されるのが配列なので、出現回数を数えるならlengthを使えばOK。

s = 'hogehoge'
p s.scan('ho')
=> ["ho", "ho"]
p s.scan('ho').length
=> 2

配列の処理

任意の数字の配列

1からnまでの数字が入った配列を作るにはこんな書き方ができる。

arry = (1..n).to_a
arry = [*1..n]

下の方がシンプルで良いかも。

ダブりをなくす

配列の中から重複をなくすにはuniqメソッドを使えば良い。

arry = [1, 1, 2, 2, 3]
p arry.uniq
=> [1, 2, 3]

順列・組合せ

permutationメソッド

ある配列の中身の順列を求めるにはpermutationメソッドを使うと便利。
そのままだとEnumeratorオブジェクトが返ってきてしまうので、.to_aで返り値を配列に入れる等の処理が必要。

arry = [1, 2, 3]
p arry.permutation.to_a
=> [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
p arry.permutation(2).to_a  #順列の個数を指定できる
=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]]

combinationメソッド

順列ではなく組合せを求めるにはcombinationメソッドを使えば良い。
こちらもEnumeratorオブジェクトが返ってきてしまうので、.to_a等をつける必要がある。

arry = [1, 2, 3, 4]
p arry.combination(3).to_a
=> [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

配列の何番目かを知りたい

indexメソッド

条件に一致するものが指定の配列の何番目(index)かを調べるメソッド。

arry = [1, 2, 3]
lists = arry.permutation.to_a
# lists = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
p lists.index([2,1,3])
=>2  # index番号を返している

数が増えてくるとindexは時間がかかるので、bsearch_indexを使うと良い。

bsearch_indexメソッド

やることはindexと同じだが、二部探索を行うので処理時間が短く済む。
一方で、bsearchするため事前にsortしておく必要がある。

arry = [1, 2, 3]
lists = arry.permutation.to_a
p lists.bsearch_index([2,1,3])
=>2 

繰り返し処理

injectメソッド

rubyでよく使うメソッドまとめ その1でも出てきたが、繰返し処理をスタイリッシュに書くならinjectメソッドが便利

# 配列オブジェクト.inject {|初期値, 要素| ブロック処理 }
nums = [1, 2, 3, 4]
p nums.inject {|sum, num| p sum += num }
=> 1, 3, 6, 10と順に表示
p nums.inject(5) {|sum, num| p sum += num }  # 初期値を指定
=> 6, 8, 11, 15と順に表示
# 最後の結果だけ取り出すならシンボル表記でOK
p nums.inject(:+)
=> 10
p nums.inject(5, :+)  # 初期値を指定
=> 15

最小公倍数・最大公約数

最小公倍数

プロコンでよく出てくるが、lcmメソッドを使えば一発。
複数の値の最小公倍数を使いたい時はinjectメソッドと組み合わせれば良い。

p 3.lcm(7)
=> 21  # 3と7の最小公倍数
nums = [2, 3, 7]
p nums.inject(:lcm)
=> 42

最大公約数

gcdメソッドを使えば一発。

p 25.gcd(30)
=> 5
nums = [1000, 20000, 200]
p nums.inject(:gcd)
=> 200

まとめ

複数の値の最小公倍数を求めたいときにinjectと組合せると、めちゃくちゃ楽に出すことができる。
処理時間もそこまでかからないし、これは便利。