Tinderbox v9 Icon

Look-up tables

(NOTE: The term 'list' may be used interchangeable with 'table'. Thus, 'look-up list' and 'look-up table' are describing the same thing.)

Look-up tables, are lists of key:value pair items allowing simple value arrays (more formally, a one-dimensional array). For those without a coding background, this is more easily understood by use of a simple example. Thus, suppose some notes record the US state (in attribute 'State') in which each customer resides. Each state is also assigned to on of a number of a regions and it is useful to know the sales region ($Region) for given customer. Previously, a usual approach to avoid setting each notes $Region by hand would be via use of conditional if() statements:

if($State=="AL") { $Region = "South";} 

However, this is a tedious process if there are many states as it needs a lot of if() statements, at least 50 in this case.

To map $State to $Region, we may make a list of key/value pairs, separated by colons, thus:

Key1:Value1;Key2:Value2

$RegionList="AL:South;AK:Central" 

Look-up tables are best stored in a List-type attribute, or a Set (a String is also allowed but not recommended). Notice that each colon-separated key:value pair is then delimited from then next pair by a semi-colon as with a normal Tinderbox list: a semi-colon is not needed after the last pair.

Keys should not consist of numbers only as this may confuse Tinderbox. Should you need to use numbered keys, perhaps because you are generating the look-up key based on a computed value, place a letter before the number. So, use 'x1' rather than just '1'.

Look-up tables are interrogated using the .lookup("key") operator like so:

$RegionList="AL:South;AK:NorthWest"; 

$Region=$RegionList.lookup("AL"); 

sets a $Region value of "South". But, if the look-up table does not contain the supplied key value, .lookup() looks for an optional special default key (default, case-sensitive) and returns that key's value or if none, an empty string is returned. So:

$Region=$RegionList.lookup("CT"); 

gives a nil value of "" as there is no matching key. If we add the option 'default' key to the look-up table:

$RegionList="AL:South;AK:NorthWest;default:Unknown"; 

Then

$Region=$RegionList.lookup("CT"); 

sets $Region to "Unknown".

The key input parameter can be evaluated. Thus if attribute $State has a value "AL", then:

$Region=$RegionList.lookup($State); 

sets a $Region value of "South".

if there is no default value defined or it defined with no value, .lookup() returns an empty string.

Storing the look-up table in one location

In the above example, the look-up table listing is stored in the note being tested, for simplicity of explanation and learning. But, in reality, this same list may need to be used in hundreds of different notes. Luckily this is easily done by defining the list in a single note and then referenced from all others by an offset attribute reference, i.e. using $AttributeName(name) or $AttributeName(path). If using this technique chose a unique note $Name, you will need to use the full $Path on the offset.

Thus these examples are more representative of real-world use:

$Region=$RegionList("config").lookup("AL") 

$Region=$RegionList("config").lookup($State) 

Noting the point about the name of the note, it may make more sense to use a deliberately unique name that also implies the note's purpose. So:

$Region=$RegionList("lt_States").lookup("AL") 

A note called 'lt_States', will stand out in action code and imply a look-up table is being referenced and when revisited months later the note's $Name may remind us as to its purpose.

More advanced look-up usage

Lookup tables are able to specify several keys that map to a common value. This is done by separating each key with the pipe character '|'. For example:

"Oliver|Micawber|Pip:Dickens;Tess:Hardy;Palliser|Finn:Trollope;default:anon" 

A structural representation of the above example is as follows. The first key/value set is in normal text, the second in italics, the third in bold, the default in plain text:

Key1-1|Key1-2|Key1-3:Value1;Key2-1:Value2;Key3-1|Key3-2:Value3;default:anon

The number of keys in each Key/Value set is discrete from other sets in the list.

Keys are matched on exact, case-sensitive, strings. In the above example "Tess" will return "Hardy" but "tess", "Tes" or "Tessa" would return "anon". If no default had been defined, an empty string "" would be returned instead for the non-matching values.

Lookup tables also permit ranges (based on case-sensitive lexical sort based matching). For example, suppose the value of $MyList is:

Alaska-Connecticut: 1; Delaware-Nebraska: 2; default: 3 

Then $MyList.lookup("Alabama") would return string "1", and $MyList.at("Illinois") would return "2". However, $MyList.lookup("alabama") returns "3" due to the way Tinderbox lexical sort works, as would. Note too, that in this case $MyList.lookup("Manitoba") would return "2" as "Manitoba" lexically sorts between "Delaware" and "Nebraska": Tinderbox has no way to know Manitoba is a Canadian province rather than a US state.

Lookup tables can also work with numeric ranges. If $MyList is:

0-10: red; 10-20: blue; default: green 

Then $MyString.lookup(5.0) returns 'red'. Note that $MyList.lookup(5) (N.B. an integer without a decimal point matches the key "5". Thus if the actual key is "5" use "5.0" to trigger the first behaviour.