はじめに
Array#firstとArray#lastは[0]
と[-1]
で代用できます。
ちなみに、[]はsliceのaliasです。
arr = [0, 1, 2, 3, 4]
arr.first #=> 0
arr[0] #=> 0
arr.last #=> 4
arr[-1] #=> 4
「first
とlast
使わなくてもいいんじゃない?」って初心者のときは思ってました...
first
とlast
を使うメリットについて、調べたこと、感じたことについてまとめてみました。
firstとlastを使うメリット
&修飾が使えるためシンプルに書ける
&:メソッド名
でメソッドを呼ぶprocがブロックに変換されます。
この記法を使えばmap
をシンプルに書けます。
arr = [['zero', 0], ['one', 1], ['two', 2]]
arr.map { |e| e[0] } #=> ["zero", "one", "two"]
# シンプルに書ける
arr.map(&:first) #=> ["zero", "one", "two"]
arr.map { |e| e[-1] } #=> [0, 1, 2]
# シンプルに書ける
arr.map(&:last) #=> [0, 1, 2]
ただし、この記法だと引数は与えられません。
Rubyの array.map(&:to_s) 記法を紐解く
[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか
を参考にしました。
レシーバがnilの場合は&.
でエラーを回避できる
first
とlast
はメソッドであるため、レシーバがnil
の場合でも、&.
を使えばエラーを回避できます。
&.
はSafe Navigation Operatorと呼ばれるもので、レシーバがnil
ならそのままnil
を返します。
Ruby2.3から使えます。
nil[0] #=> NoMethodError: undefined method `[]' for nil:NilClass
nil.first #=> NoMethodError: undefined method `first' for nil:NilClass
nil&.first #=> nil
nil[-1] #=> NoMethodError: undefined method `[]' for nil:NilClass
nil.last #=> NoMethodError: undefined method `last' for nil:NilClass
nil&.last #=> nil
Ruby の &. と #try の違い を参考にしました。
[]
でも&.
が使える
一応、[]
でも&.
を使うことはできます。実用性はないですが...
arr = [0, 1, 2, 3, 4]
arr[0] #=> 0
# .と引数を使っても書ける
arr.[](0) #=> 0
# &.を使う
arr&.[](0) #=> 0
nil&.[](0) #=> nil
引数を与える場合、直感的にわかりやすい
first
とlast
は引数で何個の要素を取るか指定できます。
-
first(n)
とすれば、先頭からn個の要素を配列で返します。 -
last(n)
とすれば、末尾からn個の要素を配列で返します。
同じことを[m, n]
で再現できます。
-
first(n)
は[0, n]
と同じ -
last(n)
は[-1, n]
と同じ
[0, n]
と[-1, n]
はわかりにくい気がします。慣れれば気にならないかも...
arr = [0, 1, 2, 3, 4]
# 先頭から数えて2つとる
arr.first(2) #=> [0, 1]
arr[0, 2] #=> [0, 1]
# 末尾から数えて3つ取る
arr.last(3) #=> [2, 3, 4]
arr[-1, 3] #=> [2, 3, 4]
コーディング規約で望ましい書き方とされている
RuboCopのコーディング規約にfitst
とlast
についての規約があります。
配列の最初や最後にアクセスしたいときは、 [0]や[-1]よりfirstやlastを使いましょう。
こちらによると理由は、
コード内でリテラルを書き散らすと一括変更やリファクタリングが面倒になるので、リテラルはなるべく1箇所にまとめるのが常道です。
だそうです。
ただし、これはRuboCopの規約を一例としてを示しただけなので、他の規約に従っても問題ないです。
おわりに
間違っていることの指摘や、他にもメリットがあればコメントで教えていただけるとありがたいです。