小ネタです。
課題
JavaScriptで [0, 1, ..., N - 1]
みたいな、要素数Nの配列が欲しくなった。本番環境に使う用のコードではなく、とりあえず開発用に動けばよい、ぐらい。
new Array(N)
で長さNの配列が得られるから、mapすれば得られるはず……と思って new Array(N).map((_, i) => i)
って書いたけどうまくいかなかった。得られるのは length
がNの配列で、要素は詰まっていないみたいな感じ。
> new Array(10) [ <10 empty items> ] > new Array(10).map((_, i) => i).forEach((x, i) => console.log(i. x)) undefined
MDNを見るとそれっぽいことがそれとなく書いてあった。言われてみれば確かに、とは思うもののびっくりする。
arrayLength
Array コンストラクターに渡された唯一の引数が 0 から 232-1 の間 (両端を含む) の整数であった場合は、新しい JavaScript の配列を返し、その length プロパティがその値になります (注: これは arrayLength 個の空のスロットを持つ配列であり、実際に undefined の値が入ったスロットではありません)。この引数がそれ以外の数値であった場合は、 RangeError 例外が発生します。
実現方法
fillする
要素が詰まってないので詰めましょう、みたいな感じ。なんでもよいので .fill(0)
とかするとタイプ数が減る。
> new Array(10).fill(0).map((_, i) => i) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
なんとしてでも要素数Nの配列を作る
mapするところは同じだけど、要素数Nの配列を作るために文字列をrepeatしてspreadする。
> [...'a'.repeat(10)].map((_, i) => i) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Array.from
を使う
Slackでこの方法を教えてもらった。fillするよりもこっちの方がもうちょっと素直そう。
> Array.from(new Array(10), (_, i) => i) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
rangeを得るメソッドのproposalがある
Number
や BigInt
に、範囲を表すイテレータを返すメソッドを生やすproposalがあることを教えてもらった。使い心地はちょうどPythonの range
関数みたいな感じ。polyfillもある。
[...Number.range(100)]
みたいに書くと所望の配列を得られそう。