Subscribed unsubscribe Subscribe Subscribe

任意の要素数の密な配列を生成するスニペット

Perlだと、

use Data::Dumper;
my @hoge = ("fuga") x 5;
print Dumper \@hoge;

__END__
$VAR1 = [
          'fuga',
          'fuga',
          'fuga',
          'fuga',
          'fuga'
        ];

みたいな感じでx演算子を使って任意の個数の密な配列を簡単に作ることができるのだけど、JavaScriptではどうしたら良いのだろう?と。
new Array()で任意のサイズの配列は作れるけど、中身が無くて各要素に値を入れることができない。

$ node
> new Array(5)
[ , , , ,  ]
> new Array(5).map(function () { return "fuga" })
[ , , , ,  ]

ただ、Array.joinを使って一度文字列を作ってsplit、とかやれば一応できる。

$ node
> Array(5).join()
',,,,'
> Array(5).join().split(',')
[ '',
  '',
  '',
  '',
  '' ]
> Array(5).join().split(',').map(function () { return "fuga" })
[ 'fuga',
  'fuga',
  'fuga',
  'fuga',
  'fuga' ]

こんな変わったやり方しかないの…?と思っていたところ、@さんに教えていただいた。

Array.apply(null, Array(N))

という方法。

$ node
> Array.apply(null, Array(5))
[ undefined,
  undefined,
  undefined,
  undefined,
  undefined ]
> Array.apply(null, Array(5)).map(function () { return "fuga" })
[ 'fuga',
  'fuga',
  'fuga',
  'fuga',
  'fuga' ]

という具合に、Array.applyへ渡す引数で任意のサイズの配列を渡すことでundefinedが詰まった配列を生成できるらしい。
でもコレはJScriptではダメだそうで… 言語仕様として定義されている動作ではないのかな…?

ちょっとよく分かりませんが、とりあえずNode.jsとかで使う分にはこの方法で良さそうな気がします。

追記

パフォーマンスも試しに測ってみました。まぁ変なことせずに素直にfor文まわした方が効率的には良さそうですね。
http://jsperf.com/create-filled-array