Share via


Maps

A map is a data type that associates one (key) value with another value. Both the key and value values may be of any valid X++ type, including objects. The types of the key and the value are given in the declaration of the map. The implementation of maps is such that access to the values is very fast.

Multiple keys may map to the same value, but one key can only map to one value at the time: Adding a (key, newvalue) where the key already exists in the map will change the association such that key maps to newvalue.

The figure below serves to explain the concept of a map, mapping names of individuals (strings) onto their ages (integers).

 

Fig 1: Maps

 
 

Maps may be traversed using the mapIterator class.

Example

{

 

// Declare a map mapping string keys onto integer values

map simap = new map(types::string, types::integer);

 

// Insert some values into the map. The map maps names to ages:

simap.insert(“Peter”, 24);

simap.insert(“Paul”, 56);

simap.insert(“Mary”, 35);

simap.insert(“John”, 56);

print simap.toString();

pause;

 

}

 
 

The (key, value) pairs in the map may be traversed using objects of type mapIterator. The value mapped to by a key may be found using the lookup method. This can be done as much a you like. Looking up a key that does not exist in the map is an error, and will raise an exception. The exists method may be used to determine if the key exists in the map.

Example

The code below illustrates inverting a map. It is only possible to invert a map if no value is mapped to by  two different keys. Comparing the number of elements in the keySet and the valueSet checks this.  Otherwise, the elements are traversed in the incoming map and inserted in the result map

Notice that the function that does the inversion (invertMap) will work irrespective of the types of the keys and values.

{

    map example;

    map invertMap(map _mapToInvert)

    {

        mapIterator it;

        map result = new map(_mapToInvert.valueType(), _mapToInvert.keyType());

        if (_mapToInvert.keySet().elements() !=

            _mapToInvert.valueSet().elements())

        {

            return null;

        }

        it = new mapIterator(_mapToInvert);

        while (it.more())

        {

            result.insert(it.value(), it.key());

            it.next();

        }

        return result;

    }

    // Fill in a few values

    example = new map(types::integer, types::string);

    example.insert (1, "one");

    example.insert (2, "two");

    print invertMap(example).toString();

    // Now two different keys (2 and 3) map to the same value, and the

    // inverse map may not be created.

    example.insert (3, "two");

    if (!invertMap(example))

        print "Could not create the map";

    pause;

}

 

The map may be rendered into human readable form by using the toString method.

 

The following methods exists on map objects:

  • public new (types keyType, types valueType)
    Creates a map, mapping values of type keyType onto values of type valueType.
     

  • public insert(any keyValue, any value)
    Inserts the pair (keyValue, value) in the map.
     

  • public boolean remove(any keyValue)
    Removes the key from the map. Returns FALSE If the key was not found in the map, and TRUE otherwise.
     

  • public any lookup(any keyValue)
    Returns the value mapped to by the given key value. If the given key is not found in the map, an exception is raised. the exists method may be used to determine if the key is found in the map.
     

  • public boolean exists(any keyValue)
    Returns TRUE if the given key value exists in the map and FALSE otherwise.
     

  • public int elements()
    Returns the number of elements in the map, that is the number of different key values.
     

  • public boolean empty()
    Returns TRUE if the map is empty i.e if it does not contain any (key, value) pairs, and FALSE otherwise. This is equivalent to (elements() == 0)
     

  • public types keyType()
    Returns the type of the key values
     

  • public types valueType()
    Returns the type of the values mapped to by the keys.
     

  • public set keySet()
    Returns the set containing the key values.

    Example

{
map ism1 = new map(types::integer, types::string);
map ism2 = new map(types::integer, types::string);
set s1, s2;
ism1.insert(1, “one”);
ism1.insert(2, “two”);
ism1.insert(3, “three”);
ism1.insert(4, “four”);
s1 = ism1.keySet();
print s1.toString();           // {1, 2, 3, 4}
print s1.definitionString();   // Set of int
s2 = ism1.valueSet();
print s2.toString();           // {”four”,  “one”, “three”, “two”}
print s2.definitionString();   // Set of str
pause;
}

  

  • public set valueSet()
    Returns the set containing the values mapped to by the keys. If all keys map on to different values, the number of elements in the set will be equal to the number of elements in the map.
     

  • public str toString()
    Returns a human readable form of the map, e.g [”Peter”->24, “Paul”->56, “Mary”->35].
     

  • public str definitionString()
    Returns a string containing the definition of the map, for example [str -> int]
     

  • public container pack()
    Packs the map into a container, suitable for saving in a database etc. If the keys or the values are objects, the pack method is called on each object to yield a (sub) container.
     

  • public static create (container c)
    Create the map previously packed by a call to pack. This is limitless. If the key or values are objects, the objects must have an unpack method that is called to reestablish their internal state from a container.
     

  • public static boolean equal(map m1, map m2)
    Returns TRUE if the two given maps are equal and FALSE otherwise. Two maps are equal if they contain the same number of elements and their key sets are the same, and each key in the keyset maps to the same value in both maps.

To learn about Mapiterators, click