JavaScriptの配列で次のことがしたい
- 要素N個の配列を連番で初期化
- 要素N個の配列をランダムに初期化
- forとか使わずにスマートにやりたい
そういう方法はもちろんあります。
JavaScriptでループを一切使わず配列を初期化。
その方法・コード例を色々まとめてみました。
このページの目次
要素N個の配列初期化にはapplyが使える
例えばN個の要素を持つ配列を作りたいとします。
愚直にループで初期化だと次のようになります
▼ N個の配列を初期化
1 2 3 4 5 6 |
const N = 100 const nums = [] for(let i=0; i<100; i++){ nums.push(i) } |
これも決して悪い方法ではありません。
でももっと便利なやり方もあります。
それはFunction.applyを使うことです。
▼ Function.applyの解説
func.apply(thisArg, [ argsArray])
argsArray 省略可 : 1つの配列風のオブジェクトであり、 func 関数が呼ぶことになる引数を列挙したものです。関数に引数が渡されない場合は null または undefined となります。返値 : 指定した this と引数で関数を呼び出した結果が返ります。
引用元 : https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
ある関数・メソッドに対して影響を受ける thisArg と、その関数を適用したい argsArray という配列(配列風オブジェクト)を渡して実行できるメソッドです。
これだけだと意味不明ですが、とても便利なものです。
ループなしで配列全要素をundefinedで初期化するコード
これを使って配列を初期化してみます。
▼ 要素N個で値がundefinedの配列として初期化
1 2 3 4 |
const N = 100 const voidArray = Array.apply(null, {length: N}) console.log('voidArray : ', voidArray) |
▼ このコードの出力結果
1 2 3 4 5 6 |
voidArray : (100) [ undefined, undefined, undefined ... ] |
最初見たときは「??」となる記述ですが、Array(配列のコンストラクタ関数)にN個の中身がない配列を渡しているのと同じになります。
コードの {length: N} ですが、違和感あるけど配列風オブジェクトとして扱われるみたいです。 length というキーを持ってるから配列風として解釈されるみたい(恐らく多分)
これを応用すれば配列初期化に便利です。
連番(0,1,2,3,4,5...)で配列を初期化してみる
まずは連番で配列を初期化してみます。
先ほどのapplyを使えばループなしで可能です。
▼ 実際に書いてみたコード例
1 2 3 4 5 6 |
const N = 100 const intArray = Array.apply( null, {length: N} ).map(Number.call, Number) console.log('intArray : ', intArray) |
▼ このコードの出力結果
1 2 3 |
intArray : (100) [ 0, 1, 2, 3, 4, 5... ] |
しっかりと連番になってます。
ポイントは Array.apply(null, {length: N}) で要素N個の配列を初期化、そのあと各要素に対してmapメソッドを使って連番になるように初期化してます。
分かりにくいのは map(Number.call, Number) の部分ですね。
これはindex番目の要素ごとに Number.call(Number, index) を呼び出し、その結果として連番配列が出来上がるという仕組みです(詳しくは Function.call とか Array.map の仕様を見ればいいと思う)
ランダムな整数で配列を初期化してみる
オマケというか応用的な方法として
ランダムな整数で配列初期化してみます。
▼ そのために書いてみたコードがこちら
1 2 3 4 5 |
const N = 100 const randArray =Array.apply(null, {length: N}).map( function(){ return Math.floor(Math.random()*N)} ) console.log('randArray : ',randArray) |
▼ このコードの出力結果
1 2 3 |
randArray : (100) [ 49, 39, 72, 59, 33, ... ] |
この例では0~99の乱数で配列を埋めてます。
ちなみに整数乱数の作り方などは次記事で書きました。
もちろんforループなどでも配列初期化は可能です。
でもコッチの方が初期化してると分かりやすいはず
応用次第では連番・乱数以外にも色々できそうです。
ただしapplyメソッドには限界が存在するので注意
ここまで書いといてなんですが…
実はapplyメソッドには渡せる引数の上限があります。
▼ 詳しくは次の記事で解説した
Maximum call stack size exceeded...
この時点でアウト。
少なくとも12.6万個以上の引数はダメみたい
より正確な値を調べると、125759個 がエラーの境界 と判明しました。つまり引数に渡せるのは 125758個 までということ。もちろんこれは 最新版Chromeで調べた値です。他ブラウザで調べてみたら、また違った結果が出てくると思います。
少なくとも要素数10万個ほどのarrayなら問題ないはずです。
でもそれ以上は保証はできません。
その点には少し注意が必要かもしれませんね。
以上、JSでランダム・連番で配列初期化でした。ではまた