The DICTIONARY function creates a new dictionary. An IDL dictionary is a compound data type that contains key-value pairs of different data types including any mixture of scalars, arrays, structures, pointers, object references, lists, hashes, and other dictionaries. Unlike HASH, the keys in a dictionary are case insensitive and must be valid IDL variable names. An IDL dictionary is very similar to an IDL structure except that it is easy to add or remove keys, or change the data type of a value.
IDL dictionaries have the following properties:
- Elements in a dictionary are unordered and are indexed by a scalar key.
- The key is a case-insensitive scalar string and must be a valid IDL variable name (i.e., no spaces or special characters).
- You can retrieve elements by using either the bracket array notation or using the "dot" syntax like an IDL structure.
- Dictionaries can change their size, growing and shrinking as elements are added or deleted.
- Unlike structures, with a dictionary you can change the data type of a value without a performance penalty.
Methods and Additional Information
Note: Since the DICTIONARY is so similar to HASH, most of the documentation can be found under HASH. Here we provide some examples of the differences between the two data types.
The DICTIONARY function and class was ported from PRO code to C/C++ code in 8.8.1. You can run the SAVEFILE_CLEANUP procedure to inspect an older save file and remove any routines that might cause problems in IDL 8.8.1 and newer. See SAVEFILE_CLEANUP for more information.
Examples
Create a dictionary containing three key-value pairs, with strings for keys.
dict = DICTIONARY("one", 1.0, "blue", [255,0,0], "Pi", !DPI)
PRINT, N_ELEMENTS(dict)
IDL prints:
3
Access and modify dictionary values using both the bracket and "dot" notation.
dict = DICTIONARY("one", 1.0, "blue", [255,0,0], "Pi", !DPI)
PRINT, dict["one"]
PRINT, dict.one
PRINT, dict.ONE
In all three cases IDL prints:
1.00000
Now try changing the data type:
dict.one = 'my value'
PRINT, dict.One
IDL prints:
my value
Now dynamically add a new key:
dict.newkey = [0,1,2]
PRINT, dict.newkey
IDL prints:
0 1 2
Create a dictionary containing all of the elements of a list
keys = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
values = LIST('one', 2.0, 3, 4l, PTR_NEW(5), {n:6}, COMPLEX(7,0))
dict = DICTIONARY(keys, values)
PRINT, N_ELEMENTS(dict)
IDL prints:
7
Create a dictionary from a structure, and also convert any substructures into dictionaries
struct = {FIELD1: 4.0, FIELD2: {SUBFIELD1: "hello", SUBFIELD2: 3.14}}
dict = DICTIONARY(struct, /EXTRACT)
PRINT, dict
PRINT, dict.field2
PRINT, 'subfield1 = ', dict.field2.subfield1
IDL prints:
FIELD2: DICTIONARY <ID=4 NELEMENTS=2>
FIELD1: 4.00000
SUBFIELD1: hello
SUBFIELD2: 3.14000
subfield1 = hello
Syntax
For details on the input arguments and keywords see HASH.
Result = DICTIONARY( Key1, Value1, Key2,
Value2, ... Keyn, Valuen, /EXTRACT , /NO_COPY )
or
Result = DICTIONARY( Keys, Values, /EXTRACT )
or
Result = DICTIONARY( Keys )
or
Result = DICTIONARY( Structure, /EXTRACT )
Arguments
Keyn
Valuen
Structure
Keywords
EXTRACT
NO_COPY
Dictionary::Count
See Hash::Count for detailed documentation.
Syntax
Result = dictionary.Count( [Value] )
Arguments
Value
Dictionary::Filter
See Hash::Filter for detailed documentation.
Syntax
Result = dictionary.Filter(Function, Args)
Arguments
Function
Args
Dictionary::HasKey
See Hash::HasKey for detailed documentation.
Syntax
Result = dictionary.HasKey( Keys )
Arguments
Keys
Dictionary::IsEmpty
See Hash::IsEmpty for detailed documentation.
Syntax
Result = dictionary.IsEmpty( )
Dictionary::IsFoldCase
See Hash::IsFoldCase for detailed documentation.
Note: This function will always return True (1) for a dictionary.
Syntax
Result = dictionary.IsFoldCase( )
Dictionary::Keys
See Hash::Keys for detailed documentation.
Syntax
Result = dictionary.Keys( )
Dictionary::Map
See Hash::Map for detailed documentation.
Syntax
Result = dictionary.Map(Function, Args)
Arguments
Function
Args
Dictionary::Reduce
See Hash::Reduce for detailed documentation.
Syntax
Result = dictionary.Reduce(Function, Args, VALUE=value)
Arguments
Function
Args
Keywords
VALUE
Dictionary::Remove
See Hash::Remove for detailed documentation.
Syntax
dictionary.Remove [, Keys] [, /ALL]
or
Result = dictionary.Remove( [, Keys] [, /ALL] )
Arguments
Keys
Keywords
ALL
Dictionary::ToStruct
See Hash::ToStruct for detailed documentation.
Syntax
Result = dictionary.ToStruct( [, MISSING=value] [, /NO_COPY] [, /RECURSIVE] [, SKIPPED=variable] )
Keywords
MISSING
NO_COPY
RECURSIVE
SKIPPED
Dictionary::Values
See Hash::Values for detailed documentation.
Syntax
Result = dictionary.Values( )
Dictionary::Where
See Hash::Where for detailed documentation.
Syntax
Result = dictionary.Where( Value [, COMPLEMENT=variable] [, COUNT=variable] [, NCOMPLEMENT=variable] )
Arguments
Value
Keywords
COMPLEMENT
COUNT
NCOMPLEMENT
Additional Information on Dictionaries
See the following sections in HASH for additional information on using dictionaries:
Dictionary Access
In many cases, you can access elements of a dictionary variable using standard IDL array syntax, as if the dictionary were a one-dimensional array. You can also access elements using standard IDL structure syntax using dot notation.
Retrieve a Single Element
To copy the value of a single dictionary element into a new variable, leaving the dictionary unchanged, use array syntax:
value = dictionary[Key]
where Key is an IDL variable containing a scalar string.
Or you can use dot notation:
value = dictionary.Key
where Key is the name of the desired element within the dictionary.
For example:
d = DICTIONARY("planet", "Saturn")
mykey = "dwarf"
PRINT, d[mykey], d["dwarf"], d.dwarf
Note: Using array notation, you are supplying a variable containing a string key. Using dot notation, you are hard-coding the key name into your program. The array notation method is more flexible because the variable can be created at runtime, while the dot notation may produce more human-readable code and is slightly faster to execute.
Note: IDL structures have a "special" parentheses syntax where you can retrieve structure fields by the tag number enclosed in parentheses. You cannot use this parentheses notation with dictionaries.
Insert a Single Element
To insert a single value into a dictionary, use array syntax or dot notation:
dictionary[Key] = Value
or
dictionary.Key = Value
where Value is the value to be stored in the new dictionary element.
Note: Using array notation, you supply a variable containing a string key. Using dot notation, you hard-code the key name into your program. The array notation method is more flexible because the variable can be created at runtime, while the dot notation may produce more human-readable code and is slightly faster to execute.
Change the Value of a Single Element
To change the value of a single dictionary element, use array syntax or dot notation:
dictionary[Key] = Value
or
dictionary.Key = Value
where Value is the new value.
Note: Using array notation, you supply a variable containing a string key. Using dot notation, you hard-code the key name into your program. The array notation method is more flexible because the variable can be created at runtime, while the dot notation may produce more human-readable code and is slightly faster to execute.
Difference between Dictionary and IDL Structures
If your dictionary contains an array, you can combine the dot notation with brackets to access a subset of the array. For example:
IDL> dict = DICTIONARY('data', FINDGEN(10))
IDL> PRINT, dict.data[2:5]
2.00000 3.00000 4.00000 5.00000
However, unlike structures, you cannot change the array elements using the dot notation:
IDL> dict = DICTIONARY('data', FINDGEN(10))
IDL> dict.data[2:5] = 0
% Attempt to store into an expression: Structure reference.
% Execution halted at: $MAIN$
Instead, use the bracket notation with multiple indexing to change just a subset. For example:
IDL> dict['data', 2:5] = 0
This is because the DICTIONARY is implemented as a container of data pointers instead of a structure that is laid out directly into memory.
Iterating over a Dictionary
Just like HASH, you can use the FOREACH operator to iterate over the dictionary.
Note: While iterating through a dictionary Avoid adding or removing elements. If the dictionary is changed during the FOREACH, the behavior is undefined.
Output
You can output a dictionary in JSON format using implied print or JSON_SERIALIZE. You can also output in YAML notation using YAML_SERIALIZE.
Version History
8.3 |
Introduced |
8.4 |
Added Filter, Map, Reduce methods
|
8.5.1 |
Added IsFoldCase method |
8.8.1 |
Ported from PRO code to C++ for performance.
|
See Also
!NULL, Creating and Defining Structures, HASH, LIST, ORDEREDHASH, Logical Operators, Modifying Object Properties, Relational Operators, Structure References, LAMBDA