LoginSignup
3
1

More than 5 years have passed since last update.

リファクタリングでコードの記述量がめっちゃ減ったお話

Last updated at Posted at 2018-12-18

先日キャプチャ数が動的に変化する正規表現の具体例の記事をあげたところ、@scivola様より丁寧にアドバイスいただき、リファクタリングを行いました。

アルファベットとハイフンから構成される文字列を、ハイフンで区切って単語部分についてcapitalizeする

これまでのコード(splitを使用)

rubypractice.rb
def word_capitalize_split(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  nstr = []
  result_split = ""
  nstr = str.split(/-/) # ハイフンで分割し配列に格納
  nstr.each do |word|
    result_split << word.capitalize + "-" # 単語をCapitalizeしハイフンと一緒に文字列に入れる
  end
  return result_split.chop # "Ruby-Php-Python-Cobol-Javascript-Java"
end

リファクタリング後(@scivola様を参考)

rubypractice.rb
def word_capitalize_split(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  str.split(/-/).map(&:capitalize).join("-") # "Ruby-Php-Python-Cobol-Javascript-Java"
end

一行で済ませることができました。
やることの考え方はほぼ一緒ですが、mapやjoinを有効活用すると圧縮できました。すごい。

これまでのコード(正規表現を使用)

rubypractice.rb
def word_capitalize_regexp(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  count = 0
  str.each_char do |n| # 単語の中のハイフンの数を数える
    if n == "-"
      count += 1
    end
  end

  if count > 0
    separator = "(.+)"
    for i in 1..count
      separator << "-(.+)" #ハイフンの数だけセパレーターに追加する
    end

    Regexp.new(separator) =~ str # ハイフン区切りで単語をキャプチャ
    result = $1.capitalize # 一つ目のキャプチャした単語をCapitalize
        # ex.1 ハマったところここから
    for i in 2..count + 1
      result << "-" + eval('$'+i.to_s).capitalize # 二つ目以降のキャプチャした単語をCapitalize
    end
        # ex.1 ここまで
    return result # "Ruby-Php-Python-Cobol-Javascript-Java"
  else
    return str.capitalize
  end
end

リファクタリング後(@scivola様のアドバイスより組み直し)

rubypractice.rb
def word_capitalize_regexp(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  Regexp.new(Array.new(str.count("-") + 1){"(.+)"}.join("-")) =~ str
  return $~.captures.map(&:capitalize).join("-") # "Ruby-Php-Python-Cobol-Javascript-Java"
end

カウントしたり正規表現用の文字列を作ったりするところが全て一行で収まりました。
String#countとかあったんですね・・・勉強になります。

gsubを使ってリファクタリング(@bogo様を参考)

rubypractice.rb
def word_capitalize_gsub(str) # str = "ruby-php-Python-COBOL-JavaScript-javA"
  str.gsub(/([A-Za-z]+)/){ $1.capitalize } # "Ruby-Php-Python-Cobol-Javascript-Java"
end

gsubでもできるというコメントをQrunchで@bogo様からいただきました。
gsubってブロック変数も使えるんですね、もっと勉強しときます。

 まとめ

工夫することにより、21行かけて書いたコードも2行に抑えることが可能という知見を得ました。
処理速度がかなり変わるはずなので、今後は徐々にコードの質にも気をつけていこうと思います。
コメントくださった方々本当にありがとうございました!

3
1
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
1