不足分をnilで埋めた配列を取得

String#split などで配列を作成する場合、指定した長さより実際の長さが短いことがある。


長さ5の配列を作りたい

"a,b,c,d,e,f,g".split(',', 5)

#=> ["a", "b", "c", "d", "e,f,g"]

"a,b,c".split(',', 5)
#=> ["a", "b", "c"] # 足りない…


Array#[]#first#take を使っても数を増やすことはできない。

ary = "a,b,c".split(',', 5)

ary[0...5]
#=> ["a", "b", "c"]
ary[0, 5]
#=> ["a", "b", "c"]

ary.first(5)
#=> ["a", "b", "c"]

ary.take(5)
#=> ["a", "b", "c"]

Array#values_at なら増やせる。

"a,b,c".split(',', 5).values_at(0...5)

#=> ["a", "b", "c", nil, nil]


破壊的に拡張したいなら、 Array#[]= で範囲外に代入する手がある。

"a,b,c".split(',', 5).tap { |a| a[5-1] = a[5-1] }

#=> ["a", "b", "c", nil, nil]

nil でなくデフォルト値があるのなら、 #zip でも良いかもしれない。

[*"1".."5"].zip("a,b,c".split(',', 5)).map { |v0,v| v || v0 }

#=> ["a", "b", "c", "4", "5"]

|| を使う場合は、偽の値( nilfalse )が既に入っていても書き換えてしまうので注意。