Dictionaries

A dictionary is flexible data structure, providing functionality very much like a database. Dictionaries:

  • Are named.
  • May optionally have an assigned text value.
  • Hold a flexible set of key-value pairs. Keys are text names.
  • Information is automatically sorted by key, resulting in fast searching and retrieval.
  • Key-value pairs can be added and removed efficiently and without limit.
  • Values may be other dictionaries, allowing you to create complex data structures.

Create a Dictionary Using the Dictionary() Function

In the following example, MyDictionary has a value of 43 and holds three name-value pairs, one of which is a dictionary having the value, "Greetings" and itself holding two name-value pairs.

MyDictionary = Dictionary();    { The dictionary is created         }
RootValue(MyDictionary) = 43;   { A root value of "43" is assigned  }

MyDictionary["ValueA"]  = 5;  { The first stored value is created }
MyDictionary["ValueB"]  = 10; { The second stored value }
MyDictionary["YourDictionary"] = Dictionary(); { The third stored value }

      { Further definition of the third stored value }
RootValue(MyDictionary["YourDictionary"]) = "Greetings";
MyDictionary["YourDictionary"]["ValueA"]  = "Good";
MyDictionary["YourDictionary"]["ValueB"]  = "Morning";

In the preceding example, the first two lines could have been combined into one as follows:

MyDictionary = Dictionary(TRUE,43); { Dictionary created and value assigned. }

The first parameter to the Dictionary function controls whether keys are case sensitive. By default (TRUE) they are not.

Attempting to simply assign a value to the dictionary as shown in the following example will not work. The dictionary structure will be lost and "MyDictionary" will simply be a variable holding the number 43;

MyDictionary = Dictionary();   { The dictionary is created         }
MyDictionary = 43;             { The dictionary is replaced by 43. }

Within a dictionary, all keys must always be unique by definition. Attempting to create a duplicate key by assigning a new value to a key with a non-unique name will simply result in the original key being assigned the new data value. Dictionaries may be defined such that their keys are case sensitive (in which case "a" will come after "Z") or they may be non case sensitive. Unless otherwise specified, they will not be case sensitive.

Root values (a value tied to the dictionary itself rather than to a key within the dictionary) are optional, but it should be noted that most operators and functions will treat dictionaries as if the dictionary was simply its root value.

Whether a dictionary contains a root value has an impact on the result that the ValueType() function will return from it.
If there is a root value then, in effect, the dictionary serves to attach metadata to that existing variable and the ValueType() command will return the value type of the root value.
If there is no root value, then the ValueType command will return type 47 from the dictionary.

Create a Dictionary Using the MetaData() Function

The function, MetaData, provides a means of attaching extended information to variables. The concept is inspired by XML. If used with a parameter that is not a dictionary, the result is to attach metadata to that object (thereby turning it into a dictionary).

MetaData(Dictionary,  Key,  [case sensitive]);

Example:

MetaData(X, "Width", 1) = 5;

X becomes a non-case sensitive dictionary, having no root value and possessing one key named "Width" that has the associated value, 5.

More commonly, you would use this to attach extended information to an existing variable as shown in the following example:

Y  =  10;
MetaData(Y,  "Area")  =  20;

In this example, Y starts as an integer and then becomes a non-case sensitive dictionary having a root value of 10 (the original value) and possessing one key named "Area" which initially has a value of 20.

You can even use this technique to turn an array into a dictionary - something that could not be done using the Dictionary() function.

Z = New(5, 10);  
MetaData(Z,  "Rate", 0) = 42.7;

Z becomes a case sensitive dictionary having a root value that is the array [5, 10]  and possessing one key named "Rate" that has a value of 42.7.

Practice with dictionaries

Arrays are useful for storing data in a clearly enumerated order, 0, 1, 2... But often, data is associated with keys that aren't in a tidy order. There are cases where driver error codes provide an excellent example of this.

In this example, you will use an array and listbox to simulate random error codes coming from hardware. A dictionary stores the key-value pairs of defined error codes and matching messages.

Create a new script application and copy the following to the Graphics submodule.

Graphics
[
  ErrCodes                      { a dictionary of error codes          };
  SimErrors                     { array simulating errors received     };
  Choice                        { selection from simulated error array };
  Index                         { offset into array                    };
  Msg                           { message to display                   };
]
Init [
  IF 1 Main;
  [
    ErrCodes = Dictionary(1);
    ErrCodes[0x2] = "No connection";
    ErrCodes[0x4] = "Missing adapter";
    ErrCodes[0x10] = "Error retrieving value";
    ErrCodes[0x30] = "Command not found";
    ErrCodes[0x92] = "Invalid syntax";
    
    SimErrors = new(5);
    SimErrors[0] = 0x2;
    SimErrors[1] = 0x4;
    SimErrors[2] = 0x10;
    SimErrors[3] = 0x30;
    SimErrors[4] = 0x92;
    
  ]
]
Main [

   System\DropList(40, 60, 140, 40 { Boundaries of list }, 
                 SimErrors { Data displayed }, 
                 "" { No title }, 
                 Index { Highlighted index }, 
                 1, 1 { Focus ID, trigger }, 
                 0 { Editable field }, 
                 Invalid { Starting value }, 
                 Choice { Variable to set }, 
                 0 { No bevel }, 
                 0 { Align top of list }); 
   Msg = Concat("Error code: ", Choice, " ... Message: ", ErrCodes[Choice]);
   ZText(150, 60, Msg, 12, 0);
]
{ End of System\Graphics }
>