Last active
March 27, 2025 22:23
-
-
Save pbartxl/abc81d99e1eac8f945417b8afcdd1b4e to your computer and use it in GitHub Desktop.
Creates a data dictionary comprising a unique key and a thunked array that it returns using GETλ. The dictionary may be built directly using formulas but a lambda function DICTIONARYλ is provided for that purpose
This file contains 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
/* NAME: GETλ | |
DESCRIPTION: Returns a data object from data-dictionary. The function takes two distinct parameter strings; | |
the first specifies the directory name and the second the keyword | |
REVISIONS: Date Developer Description | |
Dec 19 2024 Peter Bartholomew Original Development | |
*/ | |
GETλ | |
= LAMBDA(dict, LAMBDA(key, | |
LET( | |
uniqueKeys, TAKE(dict,,1), | |
objects, DROP(dict,,1), | |
object, XLOOKUP(key, uniqueKeys, objects, "keyword not found"), | |
object() | |
) | |
)); | |
/* NAME: GETVλ | |
DESCRIPTION: Returns a data object from data-dictionary. The function takes two distinct parameter strings; | |
the first specifies the directory name and the second an index specifying position within the dictionary | |
REVISIONS: Date Developer Description | |
19 Dec 2024 Peter Bartholomew Original Development | |
07 Feb 2024 Peter Bartholomew Protect against idx=0 causing Excel to crash | |
*/ | |
GETVλ | |
= LAMBDA(dict, LAMBDA([idx], | |
LET( | |
idx, 1 + MOD(idx-1, ROWS(dict)), | |
objects, DROP(dict,,1), | |
object, INDEX(objects, idx, 1), | |
object() | |
) | |
)); | |
/* NAME: GETINDEXEDλ | |
DESCRIPTION: Returns a data object from data-dictionary. The function takes two distinct parameter strings; | |
the first specifies the directory name and the second the keyword with an optional index specifying a specific term from series data | |
REVISIONS: Date Developer Description | |
Dec 19 2024 Peter Bartholomew Original Development | |
*/ | |
GETINDEXEDλ | |
= LAMBDA(dict, LAMBDA(key, [idx], | |
LET( | |
idx, IF(ISOMITTED(idx), 0, idx), | |
uniqueKeys, TAKE(dict,,1), | |
objects, DROP(dict,,1), | |
object, XLOOKUP(key, uniqueKeys, objects, LAMBDA("keyword, [" & key & "], not found")), | |
IF(AND(TYPE(idx)<>64, idx>0), INDEX(object(), idx), object()) | |
) | |
)); | |
/* NAME: KEYSλ | |
DESCRIPTION: Returns a list of keys used within a data-dictionary | |
REVISIONS: Date Developer Description | |
Dec 19 2024 Peter Bartholomew Original Development | |
*/ | |
KEYSλ = LAMBDA(dict, TAKE(dict,,1)); | |
/* NAME: DICTIONARYλ | |
DESCRIPTION: Generates a data-dictionary comprising keywords and content in pairs | |
REVISIONS: Date Developer Description | |
Dec 19 2024 Peter Bartholomew Original Development | |
*/ | |
DICTIONARYλ | |
= LAMBDA( | |
_key01, object01, | |
[_key02], [object02], | |
[_key03], [object03], | |
[_key04], [object04], | |
[_key05], [object05], | |
[_key06], [object06], | |
[_key07], [object07], | |
[_key08], [object08], | |
/* | |
[_key09], [object09], | |
[_key10], [object10], | |
[_key11], [object11], | |
[_key12], [object12], | |
[_key13], [object13], | |
[_key14], [object14], | |
[_key15], [object15], | |
[_key16], [object16], | |
*/ | |
LET( | |
// About Section | |
Help, TRIM( | |
TEXTSPLIT( | |
"FUNCTION: DICTIONARYλ(key01, object01, [key02], [object02], ...) ¶" & | |
"DESCRIPTION: →Constructor to generate a dictionary of keyword/object pairs.¶" & | |
"PARAMETERS: →¶" & | |
"key01 →(Required) Unique text identifier (keyword).¶" & | |
"object01 →(Required) An array or scalar to be stored as part of an array of thunks.¶" & | |
"key02 →(Optional) Unique text identifier (keyword).¶" & | |
"object02 →(Optional) An array or scalar to be stored as part of an array of thunks.¶" & " →Array of EBIT values.¶" & | |
" →further keyword/object pairs.¶" & | |
"→¶" & | |
"EXAMPLES: →= DICTIONARYλ(""EBIT"", EBIT, ""BaseInterest"", ...)", | |
"→", | |
"¶" | |
) | |
), | |
// Check inputs - Omitted required arguments | |
Help?, OR( | |
ISOMITTED(_key01), | |
ISOMITTED(object01), | |
), | |
NULLOMMITTED, LAMBDA(key, IF(ISOMITTED(key), "", key)), | |
_key02, NULLOMMITTED(_key02), | |
_key03, NULLOMMITTED(_key03), | |
_key04, NULLOMMITTED(_key04), | |
_key05, NULLOMMITTED(_key05), | |
_key06, NULLOMMITTED(_key06), | |
_key07, NULLOMMITTED(_key07), | |
_key08, NULLOMMITTED(_key08), | |
// Procedure | |
// Build array of unique keys | |
uniqueKeys, VSTACK(_key01, _key02,_key03,_key04,_key05,_key06,_key07,_key08), | |
// Build array of thunked arrays (also applicable to scalars) | |
objectArray, VSTACK( | |
LAMBDA(object01), LAMBDA(object02), LAMBDA(object03), LAMBDA(object04), | |
LAMBDA(object05), LAMBDA(object06), LAMBDA(object07), LAMBDA(object08) | |
), | |
// Combine unique keys with references to data objects | |
result, FILTER(HSTACK(uniqueKeys, objectArray), uniqueKeys<>""), | |
CHOOSE(Help? + 1, result, Help) | |
) | |
); | |
/* NAME: DICT3Dλ | |
DESCRIPTION: Conversts a 3D range to a data-dictionary with the content of the top-left cell being the keyname | |
REVISIONS: Date Developer Description | |
10 Jan 2024 Peter Bartholomew Original Development | |
*/ | |
DICT3Dλ | |
= LAMBDA(range3D, | |
LET( | |
nSheets, SHEETS(range3D), | |
stacked, VSTACK(range3D), | |
k, SEQUENCE(nSheets), | |
ℓ, ROWS(stacked)/nSheets, | |
block, MAPλ(k, LAMBDA(b, LAMBDA(TAKE(DROP(stacked, ℓ*(b-1)), ℓ)))), | |
name, MAP(k, LAMBDA(b, @(DROP(stacked, ℓ*(b-1))))), | |
HSTACK(name, block) | |
) | |
); | |
/* NAME: DICTIONARYCOMBINEλ | |
DESCRIPTION: Combines two or more data-dictionaris by stacking | |
REVISIONS: Date Developer Description | |
Dec 19 2024 Peter Bartholomew Original Development | |
*/ | |
DICTIONARYCOMBINEλ | |
= LAMBDA( | |
_dict01, | |
[_dict02], | |
[_dict03], | |
[_dict04], | |
[_dict05], | |
[_dict06], | |
[_dict07], | |
[_dict08], | |
LET( | |
// About Section | |
Help, TRIM( | |
TEXTSPLIT( | |
"FUNCTION: DICTIONARYλ(dict01, [dict02], ...) ¶" & | |
"DESCRIPTION: →Combine two dictionaries of keyword/object pairs.¶" & | |
"PARAMETERS: →¶" & | |
"dict01 →(Required) Named dictionary comprising keyword/object pairs.¶" & | |
"dict02 →(Required) Second dictionary to be appended to first.¶" & | |
"dict03 →(Optional) further dictionaries to be appended.¶" & | |
"→¶" & | |
"EXAMPLES: →= DICTIONARYλ(seriesDataDictionary, resultsDataDictionary) ", | |
"→", | |
"¶" | |
) | |
), | |
// Check inputs - Omitted required arguments | |
Help?, OR( | |
ISOMITTED(_dict01), | |
ISOMITTED(_dict02), | |
), | |
NULLOMMITTED, LAMBDA(dict, IF(ISOMITTED(dict), "", dict)), | |
_dict03, NULLOMMITTED(_dict03), | |
_dict04, NULLOMMITTED(_dict04), | |
_dict05, NULLOMMITTED(_dict05), | |
_dict06, NULLOMMITTED(_dict06), | |
_dict07, NULLOMMITTED(_dict07), | |
_dict08, NULLOMMITTED(_dict08), | |
// Procedure | |
// Build array of unique keys | |
combinedDict, VSTACK(_dict01, _dict02,_dict03,_dict04,_dict05,_dict06,_dict07,_dict08), | |
// Combine unique keys with references to data objects | |
result, FILTER(combinedDict, TAKE(combinedDict,,1)<>""), | |
return, CHOOSE(Help? + 1, result, Help), | |
result | |
) | |
); | |
/* NAME: PERSISTλ | |
DESCRIPTION: Outputs keywords and data from a dictionary by converting thunks back to array | |
and stacking the content by using MAPλ | |
PREREQUISITE: MAPλ function which uses thunks to return arrays of arrays from MAP | |
REVISIONS: Date Developer Description | |
Jan 03 2025 Peter Bartholomew Original Development | |
*/ | |
PERSISTλ | |
= LAMBDA(dictionary, | |
MAPλ( | |
DB.KEYSλ(dictionary), | |
LAMBDA(key, | |
LET( | |
object, DB.GETλ(dictionary)(key), | |
n, ROWS(object), | |
HSTACK(EXPAND(key,n,,""), object) | |
) | |
) | |
) | |
); | |
/* NAME: LOADDICTIONARYλ | |
DESCRIPTION: Reads keywords and data from a foratted table and converts the result to a dictionary | |
REVISIONS: Date Developer Description | |
Jan 03 2025 Peter Bartholomew Original Development | |
*/ | |
LOADDICTIONARYλ | |
= LAMBDA(dataRange, | |
LET( | |
keyColumn, TAKE(dataRange,,1), | |
objColumn, DROP(dataRange,,1), | |
recordNum, FILTER(SEQUENCE(ROWS(dataRange)), keyColumn <> ""), | |
recordEnd, VSTACK(DROP(recordNum - 1, 1), ROWS(dataRange)), | |
rangeRows, 1 + recordEnd - recordNum, | |
keyArray, FILTER(keyColumn, keyColumn <> ""), | |
objectArrϑ, MAP( | |
recordNum, | |
rangeRows, | |
LAMBDA(start, rows, LAMBDA(TRIMRANGE(TAKE(DROP(objColumn, start-1), rows)))) | |
), | |
HSTACK(keyArray, objectArrϑ) | |
) | |
); | |
// Example of a form of GETλ with a specific dictionary name hard-wired (here 'seriesDataDictionary') | |
GETSERIESDATAλ | |
= DB.GETINDEXEDλ(seriesDataDictionary) | |
; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment