reduceとflatとmap
from @takker before 2022/12
少し前のメモなので、もうご存知かもしれませんが、見かけたのでmrsekut.icon
以下の2つの文章はちょっと違和感あります
/takker/filterとmapをひとまとめにする#601cc8671280f0000093b72e
/takker/Array.prototype.flatMap()#5f62c9b41280f00000afcd91
wandbox
flatMapは、mapしてflatしたものに相当します
code:js
// flatの例
const a = [1,2,3,4].flat()
console.log(a); // 1,2,3,4
code:js
const arr = 1,2,3,4,5;
// map + flat
const f = n => n*10
const b1 = arr.map(f) // 10], 20, 30, 40, [50
.flat() // 10,20,30,40,50
// flatMap
const b2 = arr.flatMap(f) // 10,20,30,40,50
だから「filterとmapを1つに」ではなく、「flatとmapを1つに」な気がします
あ、このページでやりたかったのはmap().flat()ではなくfilter().map()ですtakker.icon
説明が足りなすぎたので追記しました
またreduceは、mapやfilterよりも抽象度の高いもので、
その証拠にreduceを使うとmapやfilterを再実装できます
code:js
const arr = 0,1,2,3,4,5,6,7,8,9,;
// map相当
const map = (arr, f) => arr.reduce((acc, cur) => acc.concat(f(cur)), [])
console.log(map(arr, n => n*10))
// filter相当
const filter = (arr, f) => arr.reduce((acc, cur) => f(cur) ? acc.concat(cur) : acc , [])
console.log(filter(arr, n => n > 3))
すごいtakker.icon
正直、Array.prototype.reduce()の抽象度が高すぎるせいか、あまり理解できていなんですよね……
なのでいつもflatmapでなんとか乗り切っていました
最近reduceを使わないと解決できない場面がちょくちょくあったので、以前よりは理解度上がっているかも……?
だから「reduceとmapの組み合わせ」という文章に違和感があります
これはreduceの役割を勘違いしていたのが原因でしたtakker.icon
/takker/Array.prototype.flatMap()#613568b61280f0000030233aに追記しました
でも狭義にはreduceって足し上げとか、配列上の全要素を舐めて得られる情報を抽出する、と自分は読むなmiyamonz.icon
Haskell界隈(?)では、こういうのを「畳み込み」と呼んでて1つの面白いトピックになってたりしますmrsekut.icon
畳み込み、面白そうですね。今度調べてみますtakker.icon
template meta programmingの文脈で出会ったことがあるような気もする……あれも畳み込みだったのかな
連結リストを扱える言語を触っているとreduceやfoldでmapやreverseのシミュレート実装が簡単にできて面白いkuuote.icon
配列を舐めて畳むという動作が綺麗に抽象化されていて感動する(個人の感想)
foldでいくつか再実装してるノートあったmrsekut.icon
/mrsekut-p/fold/unfoldの練習
サンプルコードまで書いていただきありがとうございます!takker.icon
元ページの方に修正を加えておきました