Ruby splitメソッドは引数なしのとき改行削除する

このブログで何度も登場しているsplitメソッドについて、発見があったので紹介します。

splitは、文字列を区切り文字で分割して配列に入れるメソッドですが、先頭と末尾の空白文字(改行文字など)を削除してくれるらしいのです!

splitの使用例

まずは、splitの基本から。

#引数を指定しなければ空白で分割する
p "apple banana orange".split  #=> ["apple", "banana", "orange"]

#引数を渡すと任意の文字列や正規表現で分割できる
p "リンゴとバナナとオレンジ".split("")  #=> ["リンゴ", "バナナ", "オレンジ"]

splitがあればchompはいらない?

では本題に移ります。

昨日の記事でこんなコードを書きました。

n = gets.to_i
n.times do  #以下をn回繰り返す
    ary = gets.chomp.split  #取得値をスペース区切りで分割し配列aryに要素として追加
    puts "hello = #{ary[0]}, world = #{ary[1]}"  #出力
end

#=> hello = 2, world = 5
#=> hello = 3, world = 4

3行目のary = gets.chomp.splitchompは、標準入力値に含まれる末尾の改行を削除するために書いていましたが、不要だったということですね。実際にchompを削除して実行してみたところ、同じ出力が得られました。

splitで改行が削除されることを確認してみます。以下のコードについて、入力値はa b c(文字列でスペース区切り、末尾に改行が入る)とします。

input = gets  #標準入力値を取得
p input  #=> "a b c\n"
p input.split  #=> ["a", "b", "c"]

splitで改行コード\nが削除されました!

改行コードは必ず削除されるわけではない

splitに引数を指定して、文字列で分割してみます。以下のコードについて、入力値はaとbとc(文字列で末尾に改行が入る)とします。

input = gets
p input  #=> "aとbとc\n"
p input.split('')  #=> ["a", "b", "c\n"]

改行コード\nが入ったままです。

次に、正規表現を使って分割してみます。以下のコードについて、入力値はa,b,c(文字列でコンマ区切り、末尾に改行が入る)とします。

input = gets
p input  #=> "a,b,c\n"
p input.split(/,/)  #=> ["a", "b", "c\n"]

このように、正規表現で分割するときも改行コードは削除されません。

リファレンスマニュアルは大事

to_iがあるならchompはいらないということを以前書きました。それを知ったのは、ブログを書くためにリファレンスマニュアルを読んでいたらそこに書いてあったからでした。

docs.ruby-lang.org

同様に空白文字を削除してくれるメソッドはたくさんあるのかもしれません。ネットで見かけたコードはchompsplitを一緒に使っているものばかりだったのでそれが正しいと思い込んでしまいました(間違いということでもないと思いますが)。きちんとリファレンスマニュアルを読むことは大切ですね。

splitのリファレンスマニュアルは前読んだはず…と思いながら以前のブログ記事を見返してみました。

splitは、文字列を区切り文字で分割して配列に入れるメソッドです。 split(',')のように引数に指定した任意の文字で分割することができます。 引数を省略すると空白文字(半角スペースや改行文字など)で分割されます。先頭と末尾の空白文字は削除されるので、chompは省略できるようです。

あれ?

先頭と末尾の空白文字は削除されるので、chompは省略できるようです。

今日発見したつもりが、なんと3日前にも発見してました!笑

だってリファレンスマニュアルに書いてありますから。自分の忘れっぽさを再発見。

docs.ruby-lang.org

実行速度にも影響があるらしい

以前はとにかく標準入力値を取得したらchompするものだと思っていました。

今回のコードぐらいでは速度に変化はありませんでしたが、実務や競技プログラミングでは実行速度も気になるところなので、もっともっと勉強が必要です。

こちらのブログによると、chompでも速度に影響はあるようです。 leokun0210.hatenablog.com

まとめ

splitメソッドは、以下の場合、先頭と末尾の空白文字(改行コードなど)の削除もする。

  • 引数(区切り文字)が指定されないとき
  • 引数(区切り文字)としてnilまたは' '(半角スペース1つ)が指定されたとき

スペース以外の任意の文字列や正規表現で区切る場合、空白文字(改行コードなど)は削除されない。

引数にnilやスペースを指定するのは引数を指定しないのと同じこと(かつ指定しないほうが速い)なので、splitは引数なしのとき先頭と末尾の空白文字を削除すると覚えればよさそうです。