私が歌川です

@utgwkk が書いている

JavaScriptで [0, 1, ..., N - 1] という配列を得る

小ネタです。

課題

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 例外が発生します。

developer.mozilla.org

実現方法

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
]

developer.mozilla.org

rangeを得るメソッドのproposalがある

NumberBigInt に、範囲を表すイテレータを返すメソッドを生やすproposalがあることを教えてもらった。使い心地はちょうどPythonの range 関数みたいな感じ。polyfillもある。

github.com

[...Number.range(100)] みたいに書くと所望の配列を得られそう。