JavaScript リファレンスで調べつつ、最近の書き方でやってみた。
const fizzBuzz = x =>
x % 3 === 0 && x % 5 === 0 ? "FizzBuzz"
: x % 3 === 0 ? "Fizz"
: x % 5 === 0 ? "Buzz"
: x
;
[...Array(100).keys()]
.forEach( e => console.log( fizzBuzz( e+1 ) ) )
効率とかは考えずに取り敢えず見た目でやってます。
- 三項演算子のネスト?好きかも。ガードっぽく見えてくる。
- 区切りがわからなくなるらしい。
;
が要る。 -
[...Array(100).keys()]
が[0, 1, 2...98, 99]
ってことらしい。for文ぽいものを脳内で変換するとき便利かも。 - .forEach()に登録する関数は要素、添字、配列の順で引数をとるらしい。この場合は要素eのみ。全部入りなら
(e, i, arr) => console.log( fizzBuzz( e+1 ))
みたいに書く。引数にかっこが要る。
いっそこれでいいのかな?わかりやすい。※以下、fizzBuzz() は共通なので省略
[...Array(100)]
.map( (e, i) => fizzBuzz( i+1 ) )
.forEach( e => console.log( e ) )
配列は繰り返しのための添字だけあればいいし、表示したらもう使わないので
[...Array(100)]
.forEach( (e, i) => console.log(fizzBuzz( i+1 )) )
いったん戻ってfor文。これはわかる
for(let i = 0; i < 100; i++ ){
console.log( fizzBuzz( i+1 ) );
}
ジェネレータでrange関数を作って使う
function* range(n){
for(let i = 0; i < n; i++) yield i;
}
for(const i of range(100)){
console.log( fizzBuzz( i+1 ) );
}
こんなこともできるのか。いいかどうかは謎。
function* range(n){
for(let i = 0; i < n; i++) yield i;
}
[...range(100)]
.forEach( e => console.log( fizzBuzz( e+1 ) ) )
ならこれは?
ひたすら関数をかけ続けるジェネレータ nest と、ジェネレータから有限個だけ取り出す take を定義して
function* nest(f, x){
let y=x;
while(true){
yield y
y=f(y)
}
}
const unlimitedRange = nest( n => n+1, 0 )
function* take(n,g){
for(let i=0; i<n; i++)yield g.next().value
}
[...take(100, unlimitedRange ) ]
.map( e => fizzBuzz( e+1 ) )
.forEach( e => console.log( e ) )
いけるんだ...
じゃあこれ。ジェネレータを引数にして関数 f を適用しつづけるジェネレータ mapG をプラスして...
function* take( n, g ) { for(let i=0; i<n; i++) yield g.next().value }
function* mapG( f, g ) { while(true) yield f( g.next().value ) }
function* nest( f, x ) {
let y=x
while( true ) {
yield y
y = f( y )
}
}
[...take( 100, mapG( fizzBuzz, nest( n=> n+1, 1) ) ) ]
.forEach( e => console.log( e ) )
mapがなくなり、これはこれですっきり。
どうせなら.forEach もなくしちゃお。何もせず、副作用だけ起こすジェネレータ attach を作って、
function* take( n, g ) { for( let i=0; i<n; i++ ) yield g.next().value }
function* mapG( f, g ) { while( true ) yield f( g.next().value ) }
function* nest( f, x ){
let y=x
while( true ) {
yield y
y = f( y )
}
}
function* attach(f, g) {
let x
while(true){
f(x = g.next().value)
yield x
}
}
[...take( 100, attach(console.log, mapG( fizzBuzz, nest( n=> n+1, 1) ) ) ) ]
わーい。forEachもなくなって一行になったー。