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 ; case insensitive

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"
 
; Three ways to access the same key.
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