DICTIONARY

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:

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