Last active
November 26, 2025 13:15
-
-
Save pbartxl/19464406cf298265c550baf4b3486f99 to your computer and use it in GitHub Desktop.
Excel Lambda helper functions designed to return an array of arrays (normally a #CALC! error) by retuning the nested arrays as Lambda functions (thunks) before combing them pairwise as a binary tree.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* FUNCTION NAME: SCANVλ | |
| DESCRIPTION: Implements a version of SCAN that will return a column of arrays */ | |
| /* REVISIONS: Date Developer Description | |
| 19 May 2024 Peter Bartholomew Original Development | |
| 06 Dec 2024 Peter Bartholomew Simplify definition of Fλ and use EVALTHUNKARRAYλ | |
| for compatibility with MAPλ | |
| 21 Oct 2025 Peter Bartholomew Modified to maintain consistency with SCANHλ | |
| */ | |
| SCANVλ = LAMBDA( | |
| // Parameter Declarations | |
| [y₀], | |
| [x], | |
| [FNλ], | |
| // Procedure | |
| LET( | |
| help, TRIM( | |
| TEXTSPLIT( | |
| "DESCRIPTION: →Implements a version of SCAN that will return an column of arrays.¶" & | |
| "VERSION: →06 Dec 2024 ¶" & "PARAMETERS: →¶" & | |
| " y₀ →(Required) A row vector of initial values. ¶" & | |
| " x →(Required) A column or two dimensional array of values. ¶" & | |
| " fnλ →(Required) A lambda function that accepts a two row arrays as input.", | |
| "→", | |
| "¶" | |
| ) | |
| ), | |
| // Check inputs | |
| y₀, IF(OR(ISOMITTED(y₀), y₀ = ""), #VALUE!, y₀), | |
| x, IF(OR(ISOMITTED(x), x = ""), #VALUE!, x), | |
| fnλ, IF(TYPE(fnλ) <> 128, #VALUE!, fnλ), | |
| // Procedure | |
| // n, COLUMNS(x), | |
| Fλ, LAMBDA(ϑ, xϑ, THUNK(FNλ(ϑ(), xϑ()))), | |
| // Convert initial value row to a single thunk | |
| ϑ₀, THUNK(y₀), | |
| // Convert value array to a column of thunks each representing a row array | |
| xϑ, BYROW(x, THUNK), | |
| // Implement SCAN | |
| thunkArrayϑ, SCAN(ϑ₀, xϑ, Fλ), | |
| // Recombine pairs of thunks as a binary tree until the root node is reached | |
| result, EVALTHUNKARRλ(thunkArrayϑ), | |
| // Handle Error | |
| error, MAX(ISERROR(result) + 1), | |
| // Return result | |
| CHOOSE(error, result, Help) | |
| ) | |
| ); | |
| /* FUNCTION NAME: SCANHλ | |
| DESCRIPTION: Implements a version of SCAN that will return a row of arrays */ | |
| /* REVISIONS: Date Developer Description | |
| 21 Oct 2025 Peter Bartholomew Original Development based upon SCANVλ | |
| */ | |
| SCANHλ = LAMBDA( | |
| // Parameter Declarations | |
| [y₀], | |
| [x], | |
| [FNλ], | |
| // Procedure | |
| LET( | |
| help, TRIM( | |
| TEXTSPLIT( | |
| "DESCRIPTION: →Implements a version of SCAN that will return a row of column arrays.¶" & | |
| "VERSION: →21 Oct 2025 ¶" & "PARAMETERS: →¶" & | |
| " y₀ →(Required) A column vector of initial values. ¶" & | |
| " x →(Required) A row or two dimensional array of values. ¶" & | |
| " fnλ →(Required) A lambda function that accepts two column arrays as input.", | |
| "→", | |
| "¶" | |
| ) | |
| ), | |
| // Check inputs | |
| y₀, IF(OR(ISOMITTED(y₀), y₀ = ""), #VALUE!, y₀), | |
| x, IF(OR(ISOMITTED(x), x = ""), #VALUE!, x), | |
| fnλ, IF(TYPE(fnλ) <> 128, #VALUE!, fnλ), | |
| // Procedure | |
| // n, COLUMNS(x), | |
| Fλ, LAMBDA(ϑ, xϑ, THUNK(FNλ(ϑ(), xϑ()))), | |
| // Convert initial value column to a single thunk | |
| ϑ₀, THUNK(y₀), | |
| // Convert value array to a row of thunks each representing a column array | |
| xϑ, BYCOL(x, THUNK), | |
| // Implement SCAN | |
| thunkArrayϑ, SCAN(ϑ₀, xϑ, Fλ), | |
| // Recombine pairs of thunks as a binary tree until the root node is reached | |
| result, EVALTHUNKARRλ(thunkArrayϑ), | |
| // Handle Error | |
| error, MAX(ISERROR(result) + 1), | |
| // Return result | |
| CHOOSE(error, result, Help) | |
| ) | |
| ); | |
| /* FUNCTION NAME: EVALTHUNKARRλ | |
| DESCRIPTION: Called by modified helper functions to stack the contents of any array of thunks */ | |
| /* REVISIONS: Date Developer Description | |
| 14 Oct 2024 Peter Bartholomew Extracted for MAPλ as a separate module | |
| */ | |
| EVALTHUNKARRλ = LAMBDA(thunkArrayϑ, | |
| LET( | |
| m, ROWS(thunkArrayϑ), | |
| n, COLUMNS(thunkArrayϑ), | |
| h, SEQUENCE(CEILING.MATH(LOG(n,2),1)), | |
| recombinedRowsϑ, IF( | |
| n > 1, | |
| BYROW(thunkArrayϑ, LAMBDA(thunkRowϑ, @REDUCE(thunkRowϑ, h, JOINPAIRSλ(1)))), | |
| thunkArrayϑ | |
| ), | |
| k, SEQUENCE(CEILING.MATH(LOG(m,2),1)), | |
| recombinedϑ, IF( | |
| m > 1, | |
| REDUCE(recombinedRowsϑ, k, JOINPAIRSλ(0)), | |
| recombinedRowsϑ | |
| ), | |
| result, IFNA((@recombinedϑ)(), ""), | |
| result | |
| ) | |
| ); | |
| /* FUNCTION NAME: JOINPAIRSλ | |
| DESCRIPTION: Called by EVALTHUNKARRλ to stack the contents of thunks pairwise */ | |
| /* REVISIONS: Date Developer Description | |
| 09 May 2024 Peter Bartholomew Original Development | |
| 16 May 2024 Peter Bartholomew Test for unpaired thunk in binary tree | |
| 30 Aug 2024 Peter Bartholomew Modify to stack horizontally or vertically | |
| 15 Nov 2024 David Clements Efficiency improvements / simplification | |
| */ | |
| JOINPAIRSλ = LAMBDA([by_col], LAMBDA(thunkArray, [k], | |
| LET( | |
| STACKλ, IF(by_col, HSTACK, VSTACK), | |
| alternate, WRAPROWS(thunkArray, 2), | |
| MAP( | |
| TAKE(alternate, , 1), | |
| DROP(alternate, , 1), | |
| LAMBDA(ϑ₁, ϑ₂, | |
| LET( | |
| x₁, ϑ₁(), | |
| x₂, ϑ₂(), | |
| v, IF(TYPE(ϑ₂)=16, x₁, STACKλ(x₁, x₂)), | |
| LAMBDA(v) | |
| ) | |
| ) | |
| ) | |
| ) | |
| )); | |
| THUNK = LAMBDA(x, LAMBDA(x)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment