🐂

論理演算子か、条件式ネストか

2021/01/04に公開

明けましておめでたいですね。
今朝、Rubyドリルの問題を解く中で新しい発見があったのでここに記します。

問題

二つの小文字の文字列があった時、どちらかの文字列がもう一方の文字列の語尾に位置する場合はTrueを、位置しない場合はFalseを出力するメソッドを定義する。

sliceメソッド(with range)

https://docs.ruby-lang.org/ja/latest/class/String.html

公式リファレンスよりsliceメソッドに範囲を指定する事ができると知りました。


"abcdefg".slice(0..2)

# >> abc

"abcdefg".slice(3..-1)

# >> defg

このメソッドを用いて問題のメソッドを定義。

マイアンサー


def slice_range(x, y)
  if x.length >= y.length
    if x.slice(- y.length..-1) == y
      puts "True"
    else
      puts "False"
    end
  else
    if x == y.slice(- x.length..-1)
      puts "True"
    else
      puts "False"
    end
  end
end

xとyの文字列の長さをまず条件式にかける。その後ネストにして、長い方から短い方の長さ分をスライス。

アナザーアンサー

もっと簡潔な書き方がありました。


def end_other(x, y)
  if y.slice(-x.length..- 1) == x || x.slice(- y.length..- 1) == x
    puts "True"
  else
    puts "False"
  end
end

自分の回答でこのように書かなかったのは、sliceの範囲指定がうまくいかないと思ったから。
論理演算子で分けられる条件式の一方は正常に処理が進むけどもう一方はエラーが出てしまうのでは?

そんなことなかった

コードを書き換えて検証。


def end_other(x, y)

  puts y.slice(-x.length..- 1)
  puts y.slice(-x.length..- 1)

  if y.slice(-x.length..- 1) == x || y.slice(-x.length..- 1) == x
    puts "True"
  else
    puts "False"
  end
end

end_other('xyabc', 'abc')

出力は以下通り。

            #空値です
abc
True

短い方を長い方のlengthでスライスをした時はエラーではなくnilを入れてくれていました。
このおかげでnil == xとなり、滞りなく処理が進んでくれます。

谢谢

今回の解答から、条件分岐で空値を避けるように実装しなくても簡潔にコードを書く事ができると学びました。

今後は失敗を恐れず積極的にnil込のコーディングに挑戦!

Discussion