2024/10/17:【LAMBDA】SCAN関数・REDUCE関数

≪毎週木曜12:15~ZOOMで開催中!Excel関数お勉強会の内容です。》
※【2024/10/18】一部訂正&追記を行いました。


◇関数のざっくり紹介

SCAN関数・REDUCE関数は、LAMBDA関数のヘルパー関数として
365やWeb版、スマホ版で使えるExcel関数です。

■REDUCE関数

=REDUCE([initial_value], array, lambda(アキュムレータ, 値, 本文))

REDUCE 関数 - Microsoft サポート

あえてのREDUCE関数から。
アキュムレーターとか専門用語っぽい事いわれても正直意味わからないけど
引数は「1:器」「2:配列」「3:LAMBDA(処理)」という感じ。
んで、LAMBDA(器につけた名前、配列につけた名前、処理内容)
器は料理でいう所の、お皿とかお弁当箱みたいなイメージでいいかなと。

↓画像例だと、器は「1」で「a」という仮の名前を付けた。
配列は「A1:C3(1~9の数字、9枠分)」で「b」という名前を付けた。
処理内容は「a」+「b」。

=REDUCE(1,A1:C3,LAMBDA(a,b,a+b))

REDUCE関数は、器に配列の枠分の処理を繰り返して上書き保存していく。
配列が9枠分あるので、処理は順番に9回繰り返される。
※配列の処理順番は、SEQUENCE関数で作った場合の数字の並び順と同じ。
※例の式は数字だけど、もちろん文字列の処理も行える。(SCANも同様)

① 1(器の初期値)+ 1 = 2 ⇒この結果が2回目の処理の器(a)になる。
② 2(①の結果) + 2 = 4 
③ 4 + 3 = 7

⑧ 29+ 8 = 37
⑨ 37 + 9 = 46
➡ REDUCEは上書き保存イメージなので、この「46」が最終結果となる。

=REDUCE(A1:C3,A5:C7,LAMBDA(a,b,a+b))

ちなみにさっきの式は、器が「1」というセルで言うと1枠分の大きさだったので最終結果も1枠分だったけど、↑画像の下の式のように、第1引数(器)のサイズが3*3=9枠分のセル範囲にした場合は、その全部に対して+1+2+3…
とされていくので「46~54」の3*3=9枠分の結果が出る。

ちなみにREDUCEの第2引数の配列のサイズは、別に第1引数と揃える必要はない。横長でも縦長でも何でもok。影響してくるのはその配列の枠数だけ。
(式に配列内の値を使うならそれももちろん影響するけども。)
基本的には第1引数で最終的な配列のサイズが決まって(※1)、
第2引数に入れた配列枠数で処理回数が決まる。(※2)

※1)
LambdaにVSTACK等、配列サイズを変更する処理を入れた場合を除く。
※2)
この処理回数が、あとで第1引数を省略した時の話で重要になってくる。

■SCAN関数

=SCAN ([initial_value], array, lambda(アキュムレータ, 値, 本文))

SCAN 関数 - Microsoft サポート

REDUCE関数が上書き保存だとすれば、SCAN関数は別名保存。
処理した順番で配列通りに並べて行って、最終的に1つの配列(かたまり)として結果を出す。

先ほどのREDUCE関数式をまるっとそのまま…
「REDUCE」の部分を「SCAN」に書き換えると、↑結果はこうなる。
上がREDUCE式では「46」の結果だけを出していた式。
下がREDUCE式で「46~54」の3*3=9枠分の結果が出ていた式。

SCAN関数は、処理した結果を別名保存よろしく配列の順番通りに並べるので、第1引数で単体の値じゃなく配列を指定してしまうと、下の式のように
並べていく予定の場所と被っちゃうのでエラーになる。(多次元エラー)
※ワークシート上では、1セルに複数のデータを格納した表示はできない。

結果が「46」と1つの結果しか出ていなかったREDUCE式なら、邪魔されることはないので、安心して配列通りにデータを並べていける➡結果が出せる。

SCAN関数の場合、第1引数は単純に初期値と考えて単体の値にしましょう。

ちなみに、SCAN関数が1つ前の処理のデータを保持していて
スタンプの様に順に並べていく…という事は↓こういう事も出来る。

=SCAN("",N2:N11,LAMBDA(a,b,IF(b="",a,b)))

◇第1引数を省略した場合どうなるか

■REDUCE関数

先の関数説明で、第1引数をお皿だとかお弁当箱に例えたように、本来ここは省略するべきじゃない引数なんだけど…(お皿省いて空中に盛り付け!?)
省略した場合、第1引数は…仕方ないので…取る物も取り敢えず、
第2引数の一番最初のデータを強奪して、1回目の処理結果を出す位置に
ぶちこもうとしてきます(; ・`д・´)

1つ強奪されてしまうので、第2引数の配列は1枠減ることになり、
結果として処理回数が1回分減る事になります。

↑の画像の例で言えば、上の式のような書き方をした場合、
実質、下の式のような状態になっているということになります。
(処理としては4回だけしている)

(内部的には…結果の最初の「1」は、TEXTJOINの処理を通過して文字列の「1」を出してるのではなく、単純に第2引数の(元状態の)最初の数値がそのまま入れられているだけ…)

■SCAN関数

基本的にはREDUCE関数と同じく、第2引数の一番最初のデータを強奪して、1回目の処理結果を出す位置に、LAMBDA処理を通さずにそのままぶち込んでくるのは同じです。

※ただし、SCAN関数の最終的な配列サイズは第2引数と同じであり、
 1つずつ別名保存していくので、先のREDUCE式の例と違い、
 配列一番上の値を第1引数に入れたからと言って、同じような結果に
 なるわけではないので注意が必要です。
(むしろ↑のREDUCE式の場合「1」が「1-2」に上書きされているだけ💦)

LAMBDA処理を通過している部分の結果は同じ。↑薄黄色の部分

REDUCE関数・SCAN関数での第1引数の省略に関しては、
風柳さんがTwitterで詳しく色々書いていらっしゃるので、
もっと詳しく把握したい方は・・・↓こちらへGO!(/・ω・)/

◇あとがき

…note書くのが初めて&日記とか書くのが苦手なのもあって、
なんかめっちゃ時間かかってしまった💦
ただまぁ今回は、難易度高めの関数だったからそのせいだと思いたい・・・

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
▼10/18・・あ、日付かわっちゃった・・・10/19一部更新。
風柳さんにご指摘いただいて、少し訂正&補足いれていますが
基本的には、この記事はあくまで関数教室でやった内容ではあるので
第1引数を省略時の挙動については、そのうちいつかまとめ直すかも💦
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ちなみに毎週木曜12:15頃~やっているZOOM関数教室ですが、
毎回こんなややこしいのをやっている訳もなく。
来月からは、月初か月末化あたりのどこかに恒例として数字&配列遊び回を作ろうかなと思ってます。簡易的なExcelクイズみたいなの。

四則演算(+-×÷)とあまりの出る割り算がわかれば解ける問題(…場合によってはIFとかMATCH辺りの関数を使う問題も出すかもだけど)とか。
初級者さんや場合によっては小学生でも気楽にチャレンジできそうなやつ。

なので、今回みたいな難易度高め関数はワケわからんぞー!って方でも
タイミング合えば、お気軽に覗いてもらえると嬉しいです(*´∀`*)


この記事が気に入ったらサポートをしてみませんか?