問題
以下の要件を満たすend_otherメソッドを実装しましょう。
メソッドの引数に、任意の2つの文字列を指定する。
引数に指定された2つの文字列のうち、どちらかがもう一方の文字列の末尾にある場合は、Trueを出力する
上記を満たせていない場合は、Falseを出力する
入力された文字が大文字でも小文字でも、同一の文字として処理を行う
def end_other(a, b)
# 処理を記述
end
*呼び出し例
end_other('Hiabc', 'abc')
*出力例
end_other('Hiabc', 'abc') → True
end_other('AbC', 'HiaBc') → True
end_other(‘abc’, ‘HaIoBc’) → False
私の回答
未回答(処理方法がわからず時間制限がきたため断念)
模範回答
def end_other(a, b)
a_down = a.downcase
b_down = b.downcase
a_len = a_down.length
b_len = b_down.length
if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
puts "True"
else
puts "False"
end
end
# 呼び出し例
end_other('Hiabc', 'abc')
模範解説
大文字と小文字を区別しないという条件のため、2〜3行目で任意の2つの文字列を小文字に変換しています。
4〜6行目でどちらかの文字列がもう一方の文字列の最後にある場合を区別するための処理を行っています。
slice(-(a_len)..- 1)としているのは、対象の文字列分を切り取るための記述です。
たとえば、以下のようにend_other('Hiabc', 'abc')でメソッドを呼び出し、実行した場合を考えてみましょう。
def end_other(a, b)
a_down = a.downcase
b_down = b.downcase
a_len = a_down.length
b_len = b_down.length
if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
puts "True"
else
puts "False"
end
end
end_other('Hiabc', 'abc')
すると、2〜5行目で以下のように処理されます。
a_down = hiabc
b_down = abc
a_len = 5
b_len = 3
続いて6行目で、abcの最後にHiabcが含まれているか、Hiabcの最後にabcという文字列が含まれているかを判別しています。
まずは、条件式の左辺を見て見ましょう。
b_down.slice(-(a_len)..- 1)は、b_down.slice(-5..-1)となります。しかし、b_down = abcとなっているので、インデックス番号-5から-1という条件で切り取ることができません。そのため、この部分はnilとなります。結果、nil == a_downは等しくないと評価されるので、falseになります。
続いて、条件式の右辺を見てみましょう。
a_down.slice(-(b_len)..- 1)はと、a_down.slice(-3..-1)となります。ここで、hiabcという文字列の最後にabcが含まれているかを確認したいので、abcという文字列分を左から数えます。すると、hiabcの最後までを範囲指定していることがわかります。そしてa_down = hiabcとなるので、インデックス番号-3から-1という条件で切り取るとabcが残ります。結果、abc == b_downは等しいと評価されるので、trueとなります。
感じたこと
lengthメソッドが思いつかなかった。
またsliceメソッドも理解しきれておらず、まだまだ学習が足りないと感じた。
今回の処理内容を理解し、次に同じような処理方法を行う際は何も見ずに記述できるよう
日々精進していきたい。