りゅうくんの備忘録

徒然なるままに思ったことを書くところ

reduceとかそのへん

jsでのreduceとかmapのお話

とりあえずこの記事読みながらFizzBuzzが書けるくらいのとこまで使いこなそうの会

アジェンダ的な
  • 小話
  • まずreduceってなんだよ?
  • つぎにmapってなんだよ?
  • さいごにfilterってなんだよ?
  • そしてFizzBuzzする

こんなかんじ

小話

はてな記法おぼえた(ほめて)
ブログのタグ付おぼえた(とってもほめて)
TANO*C OKINAWAがめちゃくちゃ楽しかった(うでがいたい...)

jsでのreduceだったり、mapだったりは配列にしか使えないから気を付けてねっていうお話(有能要約)
python3とかなら普通に使えるらしい?paizaのスキルチェックとかでためしてみて僕に教えて

まずreduceってなんだよ?

とりあえず構文を見てみましょう 
Array.prototype.reduce() - JavaScript | MDN から

arr.reduce(callback[, initialValue])

reduceの()の中にはコールバック関数が入るわけなんすね
コールバック関数は関数の引数として渡される関数のことです。授業でいっぱいやったねたえちゃん
たとえば

const arr = [1,2,3,4,5]
arr.reduce( (x,y) => {return x+y},0)

ってコードがあった時には

(x,y) => {return x+y}

この部分がコールバック関数になってるの!(引数に関数がきてるでしょ)

配列の各要素に対して(左から右へ)そのコールバック関数を適用して、
最終的に1つの値を返すのが reduceです

(違ってたらおしえてほしい)

次に説明したいのが

arr.reduce( (x,y) => {return x+y},0)

の  

,0

ってぶぶん

arr.reduce(callback[, initialValue])

でいうinitialValueの部分ですね。英語わかる人なら英語の通りです。それだけ
えいごむずかし><ってひともいるとおもうので説明をば。
initialValueは初期値を表してます。

const arr = [1,2,3,4,5]
arr.reduce( (x,y) => {return x+y},0)

これになぞらえて考えると、callback関数は一番最初に0を呼びだすってわけですね。

このコードがどう動くか考えてみましょう

まず arr っていう 1から5までの数字が入ってる配列があります
そいで次に、その配列に .reduce( (x,y) => {return x+y},0) ってされてますね

配列の各要素に対して(左から右へ)そのコールバック関数を適用して、最終的に1つの値を返すのが reduceです

って上で言ったのでそれに当てはめて考えていきましょう

①(x,y) => return x+ y は最初引数に 0 をとりますね (なんで?って思った人は上もっかい読んで
なので x の最初の引数は 0 です、yからは配列の要素を引数で持ってくるので y は 1 を引数にとりますね

それで面白いのはここからで、 x は次に 0+1 を引数に取ります yは2を引数にします

③これと同じように、 xは 3を引数に((0+1)+2の結果) y は4を持ってくるーって感じで処理が続きます

xは初回initialValueを引数に取った後はそれまでの計算結果を引数とします!

//①
0 + 1
//②
(0 + 1) + 2
//③
((0 + 1)+ 2) + 3

中ではこんな感じで計算されてってるわけですね!

なので

const arr = [1,2,3,4,5]
const hoge = arr.reduce( (x,y) => {return x+y},0)
console.log(hoge) // => 15

となるのです(よかったらローカルでも書いてみてね)

つぎにmapってなんだよ?

とりあえず構文をm
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map

arr.map(function callback(currentValue[, index[, array]]) {
    // Return element for new_array
}[, thisArg])

//上は詳しく正しいけどわかりにくいので
const array1 = [1, 4, 9, 16]
console.log( array1.map(x => x * 2) ) // => [2, 8, 18, 32]

mapは配列の要素をそれぞれcallback関数にかけます(個人的にはreduceよりわかりやすい)
上の説明に尽きるので、わかんないマンは僕に個人的に聞いてくれ!めーるでもついったーでもなんでも

Q: さいごにfilterってなんだよ?

A: フィルターです
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const words = ['デビルマン', 'キャシャーン', 'タイガーマスク']
const result = words.filter(word => word.length > 6)

console.log(result) // => ['タイガーマスク']

filter()の()にはコールバック関数が入る
配列の各要素に対して、この関数が true を返した要素は残され、false を返した要素はフィルターにかかって取り除かれる

つまりデビルマン以外を表示したいなら

const words = ['デビルマン', 'キャシャーン', 'タイガーマスク']
const result = words.filter(word => word.length >= 6)

console.log(result) // => [ 'キャシャーン', 'タイガーマスク' ]

こうすればいいわけですね

そしてFizzBuzzする

ここまで読んだ読書力(?)さいつよのきみならもう手が勝手にfizzbuzzを書き始めているはずだ!!!
え?かいてない?
それなら早く(自分で)書くんだよ!!1

これ答え合わせです
0604の授業の成果です filter mapとか





FizzBuzz書けない助けてママーって人向け

reduce使わないやり方で解説していきます(やさしい)

まずFizzBuzzで使う配列を用意します

const arr = [...Array(31).keys()] //[0,1,2...30]

...ってなに?蟻さん?ってひとは 
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax 
のArray を連結するってところ読んでね。


つぎにfizzbuzzしていくための機構をつくっていきます

const fizzbuzz = x => x%3 == 0 ? x%5 == 0 ? "FizzBuzz" : "Fizz" : x%5 == 0 ? "Buzz" : x

三項演算が大嫌いでゆるせないかたはifぶんでかくといいとおもいます

const fizzbuzz = x =>{
    if(x%15==0){
        return "FizzBuzz"
    }else if (x%3==0) {
        return "Fizz"
    }else if (x%5==0) {
        return "Buzz"
    }else {
        return x
    }
}


そして、FizzBuzzするときに0から始まったらこまるので、0をはぶいていきます

arr.filter(x => x>0) //[1,2...30]

最後にこいつらを合体させていきます!

arr.filter(x => x>0).map(x => fizzbuzz(x))
//どうやらmap内の関数で引数1回しか使わない場合省略してかけるらしいので
arr.filter(x => x>0).map(fizzbuzz)//でいいらしい

以上!できあがり!!第三部完!!!!

最後に

ここまで読んでくれてありがとうございます。
ブログを書くことにまだまだ慣れていないので、誤字だったり、僕が解釈違いしてて、それをそのままブログに書いちゃってる箇所などあるかもしれませんが、見つけたときはそっと僕に伝えてくれると嬉しいです(こっそり修正します)

@engs17のみんな 
ちょっと難しいかもだけどまだまだ大丈夫(たぶん)
体壊さない程度にがんばりましょ....