Haskellで書いて短いのはともかく、JSのコードがなんとも。
探してみると Array.prototype.reduce()
があった。ちゃんと要素のインデックスも渡してくれるので、これを順に足しこめばいける。
あとは要素数Nの配列をどうするか。Array(100)
とすればundefinedが100個並んだ配列が・・・できない。
Javascriptの配列はインデックスをキーとしたオブジェクトなので、通常100要素の配列というと
{ 0: undefined, 1: undefined, ..., 99: undefined, length: 100 }
といったオブジェクトになる。一方 Array(100)
で生成されるのはこんなやつ。
{ length: 100 }
何が問題かって、この歯抜け部分は Array.prototype.map()
や肝心の Array.prototype.reduce()
で無視されてしまう。 Int8Array
などの型付けされた配列を使えば各要素が0で初期化されるけど、普通のArrayでやる方法はないものか。
Create a JavaScript array containing 1...N - Stack Overflow
Array.apply(null, { length: 100 }) // もしくは Array.apply(null, Array(100))
Function.prototype.apply()
の第二引数はその関数に渡す引数の配列。そこに長さ100の(歯抜け)配列を渡しているので、 Array()
は引数100個指定されたものと思い込み、100個の引数を順番にセットした配列を作ってくれると。賢いなー。
というわけで、「1から114514まで足し算した結果をalertするプログラム」はこちら。
alert(new Int8Array(114514).reduce(function(p, c, i){ return p + i }, 0)) // もしくは alert(Array.apply(null, Array(114514)).reduce(function(p, c, i){ return p + i }, 0))
どっちにしても長い。
追記:ES6だったら Array.prototype.keys()
を使うのもよさげ。添え字が値になるし。返り値はIteratorなので、Array.from(Array(100).keys())
とか [...Array(100).keys()]
とか。
alert([...Array(100).keys()].reduce((p,c) => p + c, 0))
LINQなら keys().reduce(...)
ってできそうなのにというあれ。