Skip to content

Instantly share code, notes, and snippets.

@pbartxl
Last active March 27, 2025 22:23
Show Gist options
  • Save pbartxl/abc81d99e1eac8f945417b8afcdd1b4e to your computer and use it in GitHub Desktop.
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
/* 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