0で埋まった配列はArray(100).fill(0)でおしまいですが、[1..100]となると生のJavaScriptでは実は考えないとできません。
ツイッターで少し(空中リプで)議論したのでそのまとめしつつ思いついたものを書きます。
あらまし
JavaScriptで[1..100]みたいな配列を作るにはどうすればいいか考えていたらArray(100).fill(0).map((_,i)=>i+1)を思いついた。 pic.twitter.com/q37SMm3hIJ
— Aya (@AyaMorisawa) 2015年12月13日
このツイートを発見した私
https://twitter.com/le_panda_noir/status/681708160969670656
まあパフォーマンス考えると良い手打ってます(実は一番ではなかった)。わかりやすさも抜群です。
もうちょっとこの後改善しました
https://twitter.com/le_panda_noir/status/681717459926138880
これに対しがおさん
0始まりでいいんなら
— がお (@gaogao_9) 2015年12月29日
for(var i=100,arr=[];arr[--i]=i;);
一択なんだけどなぁ。
目からウロコですね。
わかりやすさ重視であれ書いたけど実際する時は
— がお (@gaogao_9) 2015年12月29日
for(var i=99,arr=[];arr[i]=i--;);
で1文字ケチっていけ
軽く解説
最初のAyaさんのコードと私のコードは解説いりませんよね?まんまです。mapのコールバック関数の第二引数が添字になってるということだけ少しわかりづらいですかね。
がおさんのコードは結構最適化してますね。
演算子ノ全テ - Panda Noirを見るとさらに理解が深まります(宣伝)。
順にコードを追いかけるとまず–iが評価されiが一つ減ります(i==99)。減らした後、–iは99となります(arr[99]=i)。
そしてarr[99]=iが評価されarr[99]=99となりarr[99]に99が代入され、arr[99]=99は99となります。
99はtruthyなのでループは続きます。ちなみにはじめてfalsyとなるのは0なのでそれまでループは続きます。
ワンライナー縛りなしでしてみる
ワンライナー縛りでしたが、なしだとGenerator使ってこんなこともできます。
function* iter() { var i = 1; while(true) { yield i++; } } iter.take(100);
とここでGeneratorにtakeがないと気づきました。仕方ないので拡張します
Generator.prototype.take = function(n) { var res = []; for (let i of this()) { if (n--) break; res.push(i); } return res; };
(注: パソコン起動してないので上のtake()は実際に動作確認してません。あくまでpseudoコードです)
これで上のコードで[1..100]を取得できます。短く直感的でなかなか気に入ってます。
終わりに
意外と使う場面がありますが、ワンライナーで綺麗に書けないのがもどかしかったです。
実際必要な時はだいたいlodashの_.range()使いますがね(笑)。