LoginSignup
3
3

More than 3 years have passed since last update.

【Ruby】すぐ出来る!`&:`による簡単リファクタリング

Last updated at Posted at 2019-11-08

はじめに

覚えれば誰でも出来る、でも知らないと出来ない。
そんなことって多いですよね。

きっとキレイなコードを書ける人は今回の記事にあるような内容をひたすら蓄積されているのだと思います。

まずは簡単なところから始めてみましょう!という思いで記事を書きました。

この記事が役に立つ方

  • とりあえず動くプログラムは作れる
  • でもシンプルなコードを書く引き出しを持っていない
  • Ruby初心者

この記事のメリット

  • 今までよりも5文字コードを短くできる(少ない!笑)

環境

  • Ruby 2.6.3

&:の意味

mapなどの繰り返し処理を行うメソッドと組み合わせているシーンを良く目にします。

下記コードは両方とも同じ意味です。{}内で使われています。

map{|n| n.to_s}
map(&:to_s)

つまり、
|n| n. == &:
ということですね。これで5文字削減!

正直、|って入力が面倒な場所にあるので何回も出てきてほしくないですし、読解もしやすくなるのでかなり使えます。

その他、select eachなど、頻出メソッドと良く組み合わせられるので覚えておいて損はなし!

具体例

以下のような文字列numbersがあります。

  • 奇数の中に「ひとつだけ」偶数
  • 偶数の中に「ひとつだけ」奇数

この「ひとつだけ」を見つけるためのメソッドiq_testの中身を例にします。
皆さんならどう書きますか?

“2 4 7 8 10” # numbers example 1
“1 2 1 1” # numbers example 2

まずはお恥ずかしいですが自分の拙いコードを…。以下です。

my_solution.rb
def iq_test(numbers)
  a = numbers.split( ).map{|n| n.to_i.odd?}
    if a.count(false) > 1 
      numbers.split( ).index{|x| x.to_i.odd? == true} + 1
    else
      numbers.split( ).index{|x| x.to_i.even? == true} + 1
    end
end

8行もあって、まだまだリファクタリングの余地がありますね。
そして、次がプロフェッショナルのコードです。

Pro_solution.rb
def iq_test(numbers)
  nums = numbers.split.map(&:to_i).map(&:even?)
  nums.count(true) > 1 ? nums.index(false) + 1 : nums.index(true) + 1
end

5行でシンプル!今回の&:に加えてifの代わりに三項演算子を使っていますが、意味が読み取れる程度に使用されていて、いいコードですよね。

キレイ。

おわりに

最近この記事を読んだ影響で、Codewarsという英語のプログラム課題サイトを利用し始めました。
英語の勉強にもいいですね!

今回の例題もその中で登場したものです。
解けば解くほど、リファクタリングの引き出しが増えて楽しい!

参考にさせて頂いたサイト(いつもありがとうございます)

Train with Programming Challenges/Kata | Codewars

3
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3