単にcdrっぽい事をしたい場合、
dropを使った方がシンプルになります。
コチラの記事を参照
配列系では、-1は末尾を示します。
sliceで-1を指定すると、末尾を返してくれます。
あらかじめサイズを知ってる必要がないので楽で良いですね。
> [1,2,3].slice(-1) => 3
これと範囲指定を組み合わせると、配列のサイズに関係なく、先頭を除いた配列を手にする事が出来ます。
「...」は例の如く境界を含まないので更に尻尾も排除してくれます。
> [1,2,3].slice(1..-1) => [2, 3] > [1,2,3,4,5,6,7,8,9,10].slice(1..-1) => [2, 3, 4, 5, 6, 7, 8, 9, 10] > [1,2,3,4,5,6,7,8,9,10].slice(1...-1) => [2, 3, 4, 5, 6, 7, 8, 9]
今回はcdrっぽい挙動をするメソッドが欲しかったので、こうしました。
cdrは非破壊メソッドです。
- cdrモドキをしたい場合は「!」抜き
- slice以降、先頭以外は絶対必要ない場合は「!」付き
という使い分けができます。
> a = [1,2,3,4] => [1, 2, 3, 4] > a.slice(1,-1) => nil > a.slice(1..-1) => [2, 3, 4] > a => [1, 2, 3, 4] > a.slice!(1..-1) => [2, 3, 4] > a => [1]
おまけ
ちなみに、第二変数に負の数値を指定した場合、nilを返して来ます。
> [1,2,3,4,5,6,7,8,9,10].slice(1,-1) => nil
実際の方法
以上を応用すると、以前書いた各月の第一週の曜日と週番号を調べるRubyスクリプトは
$ ruby -r 'date' -e 'puts (1..12).map {|i| %Q( %2s/1 Week #%2s %s) % [d = Date.new(2013,i,1), i, d.cweek, d.strftime("%A")].slice(1..-1) }' 1/1 Week # 1 Tuesday 2/1 Week # 5 Friday 3/1 Week # 9 Friday 4/1 Week #14 Monday 5/1 Week #18 Wednesday 6/1 Week #22 Saturday 7/1 Week #27 Monday 8/1 Week #31 Thursday 9/1 Week #35 Sunday 10/1 Week #40 Tuesday 11/1 Week #44 Friday 12/1 Week #48 Sunday
とワンライナー化できます。*1
変数d = Date.newのためにセミコロンを使わなくて良くなりました。
最後まで読まないと本当に代入する変数が分からないのがイマイチな気はしますが……
*1:細かいとこを少し変えましたが