Chapter 12. 函式 (七):自定義函式12.4 LAMBDA 輔助函式

12.4 LAMBDA 輔助函式


LAMBDA 輔助函式共有六個,專門與 LAMBDA 搭配使用,分別如下:

  • MAP:同時對多個範圍使用 LAMBDA 函式

語法

MAP (陣列_1, [陣列_2,...], LAMBDA)

輸入

  • 陣列_n:要使用 LAMBDA 的範圍,要和 LAMBDA 的輸入數量相同,且各 陣列_n 的範圍大小要相同,例如都是 2 欄 × 3 列等。
  • LAMBDA:LAMBDA 函式。

輸出

各個 陣列_n 使用 LAMBDA 的結果,輸出範圍同 陣列_n 的範圍大小。

  • BYROW / BYCOL:以列 / 欄為單位的使用 LAMBDA 函式

語法

BYROW / BYCOL (陣列或範圍, LAMBDA)

輸入

  • 陣列或範圍:要使用 LAMBDA 的陣列或範圍。
  • LAMBDA:有一個 變數 的 LAMBDA 函式。

輸出

  • BYROW:逐列使用 LAMBDA,輸出範圍同 陣列或範圍 的列數。
  • BYCOL:逐欄使用 LAMBDA,輸出範圍同 陣列或範圍 的欄數。
  • SCAN / REDUCE:以迴圈的方式執行 LAMBDA 函式

語法

SCAN / REDUCE (初始值, 陣列或範圍, LAMBDA)

輸入

  • 初始值:第一次執行 LAMBDA 的初始值。
  • 陣列或範圍:要使用 LAMBDA 的陣列或範圍。
  • LAMBDA:有兩個 變數 的 LAMBDA 函式。

輸出

將每次 LAMBDA 的輸出作為下一次的 變數_1,假設 陣列或範圍 共有 n 個值,分別為 輸入值_n 其執行步驟如下:

  • Step 1:LAMBDA(初始值, 輸入值_1,...),輸出 中繼值_1
  • Step 2~n-1:計算 LAMBDA(中繼值_x, 輸入值_x+1,...),輸出 中繼值_x+1
  • Step n:計算 LAMBDA(中繼值_n-1, 輸入值_n,...),輸出 中繼值_n

SCAN / REDUCE 的輸出分別如下:

  • SCAN:中繼值_1 ~ 中繼值_n,輸出範圍同 陣列或範圍
  • REDUCE:只輸出 中繼值_n

  • MAKEARRAY:讓 LAMBDA 輸出多列、多欄的陣列

語法

MAKEARRAY (列數, 欄數, LAMBDA)

輸入

  • 列數 / 欄數:要輸出的列 / 欄數。
  • LAMBDA:有兩個 變數 的 LAMBDA 函式。

輸出

使用 LAMBDA(當前列,當前欄,公式) 的結果,輸出範圍共有 列數 列、欄數 欄,如下圖,左圖直接輸出當前是第幾列、右圖直接輸出當前是第幾欄。

以上函式缺乏例子有點難理解,接下來分別使用四個範例說明各函式的適用時機:

  1. 根據會員的生日輸出會員的年齡,如下圖:

    公式

    C2 的公式為 =MAP(B2:B,LAMBDA(生日,AGE(生日)))

    解說

    • 要將整欄使用相同的公式,因此適合使用 MAP 完成。
    • 在此使用 =ARRAYFORMULA(AGE(B2:B)) 其實比 MAP 直觀。
  2. 計算每位客戶一到六月的金額總計,及每個月所有客戶的金額總計,如下圖:

    公式

    • H2 的公式為 =BYROW(B2:G11,LAMBDA(值,SUM(值)))
    • B12 的公式為 =BYCOL(B2:H11,LAMBDA(值,SUM(值)))

    解說

    以下以 H2 為例,B12 的概念相同只是換成逐欄加總

    • 在 H2:H11 中,要將每一列 B:G 欄的值加總,但 ARRAYFORMULA+SUM 無法針對每一列個別加總,因此需要用到 BYROW + LAMBDA(SUM) 完成。
    • 在 LAMBDA 中,使用 SUM 將所有值加總,再套上一層 BYROW 之後,就會將 B2:G2、B3:G3、...、B11:G11 依序套入 BYROW 中,輸出每一列加總的結果。
  3. 根據每天的安打、打數,計算出截至當天的打擊率 (累積安打 / 累積打數),如下圖:

    公式

    =MAP(SCAN(0,B2:B,LAMBDA(累積安打,今日安打,累積安打+今日安打)),SCAN(0,C2:C,LAMBDA(累積打數,今日打數,累積打數+今日打數)),LAMBDA(累積安打,累積打數,累積安打/累積打數))

    解說

    本範例較複雜,以下分成多個步驟說明:

    • SCAN 可以計算累積安打及打數,但 SCAN 只能有一個陣列或範圍的輸入,因此只能分別算出累積安打、累積打數,並沒有辦法一次完成。在此會需要使用 MAP 計算兩者相除的結果。即 =MAP([累積安打], [累積打數], LAMBDA(累積安打,累積打數,累積安打/累積打數))。
    • 累積安打的計算方式為 SCAN(0,B2:B,LAMBDA(累積安打,今日安打,累積安打+今日安打),初始值為 0
    • 累積打數與累積安打的算法相同,在此省略。
  4. 製作一張乘法表,計算 11~19 的兩兩相乘值,如下圖:

    公式

    =MAKEARRAY(9,9,LAMBDA(列,欄,(列+10)*(欄+10)))

    解說

    • 在此要相乘的數字是遞增的,因此可以使用 MAKEARRAY 完成,11~19 共九個數字,因此 列數欄數 都設為 9
    • 在 LAMBDA 中列、欄會分別是 1~9,因此要計算 11~19 相乘需要分別加上 10,即 (列+10)*(欄+10)。
    • 在此也可以使用 =ARRAYFORMULA(A2:A10*B1:J1) 完成,因為 A2:A10B1:J1 分別是單欄、單列的值,比 MAKEARRAY 更方便且直觀。若不要使用到儲存格的數字,則可以使用 =ARRAYFORMULA(
      SEQUENCE(9,1,11,1)*SEQUENCE(1,9,11,1)) 完成。

在上述的範例中,我將所有可以使用 ARRAYFORMULA 代替的範例都補上 ARRAYFORMULA 的做法,是因為作者對 LAMBDA 與 ARRAYFORMULA 兩者的取捨標準為如果 ARRAYFORMULA 無法完成,就使用 LAMBDA (例如 SUMIFS),雖然 LAMBDA 函式的用途與功能更多元,但 ARRAYFORMULA 的做法更為直觀,實務上大家可以依據自己的使用習慣決定使用哪一個函式。