8.32 Map (hash table)

A map is a special array, often called an associative array or dictionary, in which the index to the data can be any Euphoria object and not just an integer. These sort of indexes are also called keys. For example we can code things like this...

custrec = new() -- Create a new map
   put(custrec, "Name", "Joe Blow")
   put(custrec, "Address", "555 High Street")
   put(custrec, "Phone", 555675632)

This creates three elements in the map, and they are indexed by "Name", "Address" and "Phone", meaning that to get the data associated with those keys we can code ...

object data = get(custrec, "Phone")
   -- data now set to 555675632

Note: Only one instance of a given key can exist in a given map, meaning for example, we couldn't have two separate "Name" values in the above custrec map.

Maps automatically grow to accommodate all the elements placed into it.

Associative arrays can be implemented in many different ways, depending on what efficiency trade-offs have been made. This implementation allows you to decide if you want a small map or a large map.

small map
Faster for small numbers of elements. Speed is usually proportional to the number of elements.
large map
Faster for large number of elements. Speed is usually the same regardless of how many elements are in the map. The speed is often slower than a small map.
Note: If the number of elements placed into a small map take it over the initial size of the map, it is automatically converted to a large map.

8.32.1 Operation codes for put

8.32.1.1 PUT

include std/map.e
namespace map
public enum PUT

8.32.1.2 ADD

include std/map.e
namespace map
public enum ADD

8.32.1.3 SUBTRACT

include std/map.e
namespace map
public enum SUBTRACT

8.32.1.4 MULTIPLY

include std/map.e
namespace map
public enum MULTIPLY

8.32.1.5 DIVIDE

include std/map.e
namespace map
public enum DIVIDE

8.32.1.6 APPEND

include std/map.e
namespace map
public enum APPEND

8.32.1.7 CONCAT

include std/map.e
namespace map
public enum CONCAT

8.32.1.8 LEAVE

include std/map.e
namespace map
public enum LEAVE

8.32.2 Types of Maps

8.32.2.1 SMALLMAP

include std/map.e
namespace map
public constant SMALLMAP

8.32.2.2 LARGEMAP

include std/map.e
namespace map
public constant LARGEMAP

8.32.3 Types

8.32.3.1 map

include std/map.e
namespace map
public type map(object obj_p)

Defines the datatype 'map'

Comments:

Used when declaring a map variable.

Example:
map SymbolTable = new() -- Create a new map to hold the symbol table.

8.32.4 Routines

8.32.4.1 calc_hash

include std/map.e
namespace map
public function calc_hash(object key_p, integer max_hash_p)

Calculate a Hashing value from the supplied data.

Parameters:
  1. key_p : The data for which you want a hash value calculated.
  2. max_hash_p : The returned value will be no larger than this value.
Returns:

An integer, the value of which depends only on the supplied data.

Comments:

This is used whenever you need a single number to represent the data you supply. It can calculate the number based on all the data you give it, which can be an atom or sequence of any value.

Example 1:
integer h1
-- calculate a hash value and ensure it will be a value from 1 to 4097.
h1 = calc_hash( symbol_name, 4097 )

8.32.4.2 threshold

include std/map.e
namespace map
public function threshold(integer new_value_p = 0)

Gets or Sets the threshold value that determines at what point a small map converts into a large map structure. Initially this has been set to 23, meaning that maps up to 23 elements use the small map structure.

Parameters:
  1. new_value_p : If this is greater than zero then it sets the threshold value.
Returns:

An integer, the current value (when new_value_p is less than 1) or the old value prior to setting it to new_value_p.

8.32.4.3 type_of

include std/map.e
namespace map
public function type_of(map the_map_p)

Determines the type of the map.

Parameters:
  1. m : A map
Returns:

An integer, Either SMALLMAP or LARGEMAP

8.32.4.4 rehash

include std/map.e
namespace map
public procedure rehash(integer the_map_p, integer requested_bucket_size_p = 0)

Changes the width, i.e. the number of buckets, of a map. Only effects large maps.

Parameters:
  1. m : the map to resize
  2. requested_bucket_size_p : a lower limit for the new size.
Comment:

If requested_bucket_size_p is not greater than zero, a new width is automatically derived from the current one.

See Also:

statistics, optimize

8.32.4.5 new

include std/map.e
namespace map
public function new(integer initial_size_p = 690)

Create a new map data structure

Parameters:
  1. initial_size_p : An estimate of how many initial elements will be stored in the map. If this value is less than the threshold value, the map will initially be a small map otherwise it will be a large map.
Returns:

An empty map.

Comments:

A new object of type map is created. The resources allocated for the map will be automatically cleaned up if the reference count of the returned value drops to zero, or if passed in a call to delete.

Example 1:
map m = new()  -- m is now an empty map
map x = new(threshold()) -- Forces a small map to be initialized
x = new()    -- the resources for the map previously stored in x are released automatically
delete( m )  -- the resources for the map are released

8.32.4.6 new_extra

include std/map.e
namespace map
public function new_extra(object the_map_p, integer initial_size_p = 690)

Returns either the supplied map or a new map.

Parameters:
  1. the_map_p : An object, that could be an existing map
  2. initial_size_p : An estimate of how many initial elements will be stored in a new map.
Returns:

A map, If m is an existing map then it is returned otherwise this returns a new empty map.

Comments:

This is used to return a new map if the supplied variable isn't already a map.

Example 1:
map m = new_extra( foo() ) -- If foo() returns a map it is used, otherwise
                           --  a new map is created.

8.32.4.7 compare

include std/map.e
namespace map
public function compare(map map_1_p, map map_2_p, integer scope_p = 'd')

Compares two maps to test equality.

Parameters:
  1. map_1_p : A map
  2. map_2_p : A map
  3. scope_p : An integer that specifies what to compare.
    • 'k' or 'K' to only compare keys.
    • 'v' or 'V' to only compare values.
    • 'd' or 'D' to compare both keys and values. This is the default.
Returns:

An integer,

  • -1 if they are not equal.
  • 0 if they are literally the same map.
  • 1 if they contain the same keys and/or values.
Example 1:
map map_1_p = foo()
map map_2_p = bar()
if compare(map_1_p, map_2_p, 'k') >= 0 then
     ... -- two maps have the same keys

8.32.4.8 has

include std/map.e
namespace map
public function has(integer the_map_p, object the_key_p)

Check whether map has a given key.

Parameters:
  1. the_map_p : the map to inspect
  2. the_key_p : an object to be looked up
Returns:

An integer, 0 if not present, 1 if present.

Example 1:
map the_map_p
the_map_p = new()
put(the_map_p, "name", "John")
? has(the_map_p, "name") -- 1
? has(the_map_p, "age")  -- 0
See Also:

get

8.32.4.9 get

include std/map.e
namespace map
public function get(integer the_map_p, object the_key_p, object default_value_p = 0)

Retrieves the value associated to a key in a map.

Parameters:
  1. the_map_p : the map to inspect
  2. the_key_p : an object, the the_key_p being looked tp
  3. default_value_p : an object, a default value returned if the_key_p not found. The default is 0.
Returns:

An object, the value that corresponds to the_key_p in the_map_p. If the_key_p is not in the_map_p, default_value_p is returned instead.

Example 1:
map ages
ages = new()
put(ages, "Andy", 12)
put(ages, "Budi", 13)

integer age
age = get(ages, "Budi", -1)
if age = -1 then
    puts(1, "Age unknown")
else
    printf(1, "The age is %d", age)
end if
See Also:

has

8.32.4.10 nested_get

include std/map.e
namespace map
public function nested_get(map the_map_p, sequence the_keys_p, object default_value_p = 0)

Returns the value that corresponds to the object the_keys_p in the nested map the_map_p. the_keys_p is a sequence of keys. If any key is not in the map, the object default_value_p is returned instead.

8.32.4.11 put

include std/map.e
namespace map
public procedure put(integer the_map_p, object the_key_p, object the_value_p,
        integer operation_p = map :PUT, integer trigger_p = threshold_size)

Adds or updates an entry on a map.

Parameters:
  1. the_map_p : the map where an entry is being added or updated
  2. the_key_p : an object, the the_key_p to look up
  3. the_value_p : an object, the value to add, or to use for updating.
  4. operation : an integer, indicating what is to be done with the_value_p. Defaults to PUT.
  5. trigger_p : an integer. Default is the current threshold size. See Comments for details.
Comments:
  • The operation parameter can be used to modify the existing value. Valid operations are:
    • PUT -- This is the default, and it replaces any value in there already
    • ADD -- Equivalent to using the += operator
    • SUBTRACT -- Equivalent to using the -= operator
    • MULTIPLY -- Equivalent to using the *= operator
    • DIVIDE -- Equivalent to using the /= operator
    • APPEND -- Appends the value to the existing data
    • CONCAT -- Equivalent to using the &= operator
    • LEAVE -- If it already exists, the current value is left unchanged otherwise the new value is added to the map.
  • The trigger parameter is used when you need to keep the average number of keys in a hash bucket to a specific maximum. The trigger value is the maximum allowed. Each time a put operation increases the hash table's average bucket size to be more than the trigger value the table is expanded by a factor of 3.5 and the keys are rehashed into the enlarged table. This can be a time intensive action so set the value to one that is appropriate to your application.
    • By keeping the average bucket size to a certain maximum, it can speed up lookup times.
    • If you set the trigger to zero, it will not check to see if the table needs reorganizing. You might do this if you created the original bucket size to an optimal value. See new on how to do this.
Example 1:
map ages
ages = new()
put(ages, "Andy", 12)
put(ages, "Budi", 13)
put(ages, "Budi", 14)

-- ages now contains 2 entries: "Andy" => 12, "Budi" => 14
See Also:

remove, has, nested_put

8.32.4.12 nested_put

include std/map.e
namespace map
public procedure nested_put(map the_map_p, sequence the_keys_p, object the_value_p,
        integer operation_p = PUT, integer trigger_p = threshold_size)

Adds or updates an entry on a map.

Parameters:
  1. the_map_p : the map where an entry is being added or updated
  2. the_keys_p : a sequence of keys for the nested maps
  3. the_value_p : an object, the value to add, or to use for updating.
  4. operation_p : an integer, indicating what is to be done with value. Defaults to PUT.
  5. trigger_p : an integer. Default is the current threshold size. See Comments for details.
Valid operations are:
  • PUT -- This is the default, and it replaces any value in there already
  • ADD -- Equivalent to using the += operator
  • SUBTRACT -- Equivalent to using the -= operator
  • MULTIPLY -- Equivalent to using the *= operator
  • DIVIDE -- Equivalent to using the /= operator
  • APPEND -- Appends the value to the existing data
  • CONCAT -- Equivalent to using the &= operator
Comments:
  • If existing entry with the same key is already in the map, the value of the entry is updated.
  • The trigger parameter is used when you need to keep the average number of keys in a hash bucket to a specific maximum. The trigger value is the maximum allowed. Each time a put operation increases the hash table's average bucket size to be more than the trigger value the table is expanded by a factor 3.5 and the keys are rehashed into the enlarged table. This can be a time intensive action so set the value to one that is appropriate to your application.
    • By keeping the average bucket size to a certain maximum, it can speed up lookup times.
    • If you set the trigger to zero, it will not check to see if the table needs reorganizing. You might do this if you created the original bucket size to an optimal value. See new on how to do this.
Example 1:
map city_population
city_population = new()
nested_put(city_population, {"United States", "California", "Los Angeles"},
    3819951 )
nested_put(city_population, {"Canada",        "Ontario",    "Toronto"},     
    2503281 )
See also:

put

8.32.4.13 remove

include std/map.e
namespace map
public procedure remove(map the_map_p, object the_key_p)

Remove an entry with given key from a map.

Parameters:
  1. the_map_p : the map to operate on
  2. key : an object, the key to remove.
Comments:
  • If key is not on the_map_p, the the_map_p is returned unchanged.
  • If you need to remove all entries, see clear
Example 1:
map the_map_p
the_map_p = new()
put(the_map_p, "Amy", 66.9)
remove(the_map_p, "Amy")
-- the_map_p is now an empty map again
See Also:

clear, has

8.32.4.14 clear

include std/map.e
namespace map
public procedure clear(map the_map_p)

Remove all entries in a map.

Parameters:
  1. the_map_p : the map to operate on
Comments:
  • This is much faster than removing each entry individually.
  • If you need to remove just one entry, see remove
Example 1:
map the_map_p
the_map_p = new()
put(the_map_p, "Amy", 66.9)
put(the_map_p, "Betty", 67.8)
put(the_map_p, "Claire", 64.1)
...
clear(the_map_p)
-- the_map_p is now an empty map again
See Also:

remove, has

8.32.4.15 size

include std/map.e
namespace map
public function size(map the_map_p)

Return the number of entries in a map.

Parameters:

the_map_p : the map being queried

Returns:

An integer, the number of entries it has.

Comments:

For an empty map, size will be zero

Example 1:
map the_map_p
put(the_map_p, 1, "a")
put(the_map_p, 2, "b")
? size(the_map_p) -- outputs 2
See Also:

statistics

8.32.4.16 NUM_ENTRIES

include std/map.e
namespace map
public enum NUM_ENTRIES

8.32.4.17 NUM_IN_USE

include std/map.e
namespace map
public enum NUM_IN_USE

8.32.4.18 NUM_BUCKETS

include std/map.e
namespace map
public enum NUM_BUCKETS

8.32.4.19 LARGEST_BUCKET

include std/map.e
namespace map
public enum LARGEST_BUCKET

8.32.4.20 SMALLEST_BUCKET

include std/map.e
namespace map
public enum SMALLEST_BUCKET

8.32.4.21 AVERAGE_BUCKET

include std/map.e
namespace map
public enum AVERAGE_BUCKET

8.32.4.22 STDEV_BUCKET

include std/map.e
namespace map
public enum STDEV_BUCKET

8.32.4.23 statistics

include std/map.e
namespace map
public function statistics(map the_map_p)

Retrieves characteristics of a map.

Parameters:
  1. the_map_p : the map being queried
Returns:

A sequence, of 7 integers:

  • NUM_ENTRIES -- number of entries
  • NUM_IN_USE -- number of buckets in use
  • NUM_BUCKETS -- number of buckets
  • LARGEST_BUCKET -- size of largest bucket
  • SMALLEST_BUCKET -- size of smallest bucket
  • AVERAGE_BUCKET -- average size for a bucket
  • STDEV_BUCKET -- standard deviation for the bucket length series
Example 1:
sequence s = statistics(mymap)
printf(1, "The average size of the buckets is %d", s[AVERAGE_BUCKET])

8.32.4.24 keys

include std/map.e
namespace map
public function keys(map the_map_p, integer sorted_result = 0)

Return all keys in a map.

Parameters:
  1. the_map_p: the map being queried
  2. sorted_result: optional integer. 0 [default] means do not sort the output and 1 means to sort the output before returning.
Returns:

A sequence made of all the keys in the map.

Comments:

If sorted_result is not used, the order of the keys returned is not predicable.

Example 1:
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence keys
keys = keys(the_map_p) -- keys might be {20,40,10,30} or some other order
keys = keys(the_map_p, 1) -- keys will be {10,20,30,40}
See Also:

has, values, pairs

8.32.4.25 values

include std/map.e
namespace map
public function values(map the_map, object keys = 0, object default_values = 0)

Return values, without their keys, from a map.

Parameters:
  1. the_map : the map being queried
  2. keys : optional, key list of values to return.
  3. default_values : optional default values for keys list
Returns:

A sequence, of all values stored in the_map.

Comments:
  • The order of the values returned may not be the same as the putting order.
  • Duplicate values are not removed.
  • You use the keys parameter to return a specific set of values from the map. They are returned in the same order as the keys parameter. If no default_values is given and one is needed, 0 will be used.
  • If default_values is an atom, it represents the default value for all values in keys.
  • If default_values is a sequence, and its length is less than keys, then the last item in default_values is used for the rest of the keys.
Example 1:
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence values
values = values(the_map_p)
-- values might be {"twenty","forty","ten","thirty"}
-- or some other order
Example 2:
map the_map_p
the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence values
values = values(the_map_p, { 10, 50, 30, 9000 })
-- values WILL be { "ten", 0, "thirty", 0 }
values = values(the_map_p, { 10, 50, 30, 9000 }, {-1,-2,-3,-4})
-- values WILL be { "ten", -2, "thirty", -4 }
See Also:

get, keys, pairs

8.32.4.26 pairs

include std/map.e
namespace map
public function pairs(map the_map_p, integer sorted_result = 0)

Return all key/value pairs in a map.

Parameters:
  1. the_map_p : the map to get the data from
  2. sorted_result : optional integer. 0 [default] means do not sort the output and 1 means to sort the output before returning.
Returns:

A sequence, of all key/value pairs stored in the_map_p. Each pair is a sub-sequence in the form {key, value}

Comments:

If sorted_result is not used, the order of the values returned is not predicable.

Example 1:
map the_map_p

the_map_p = new()
put(the_map_p, 10, "ten")
put(the_map_p, 20, "twenty")
put(the_map_p, 30, "thirty")
put(the_map_p, 40, "forty")

sequence keyvals
keyvals = pairs(the_map_p) 
-- might be {{20,"twenty"},{40,"forty"},{10,"ten"},{30,"thirty"}}

keyvals = pairs(the_map_p, 1) 
-- will be {{10,"ten"},{20,"twenty"},{30,"thirty"},{40,"forty"}}
See Also:

get, keys, values

8.32.4.27 optimize

include std/map.e
namespace map
public procedure optimize(map the_map_p, integer max_p = threshold_size, atom grow_p = 1.333)

Widens a map to increase performance.

Parameters:
  1. the_map_p : the map being optimized
  2. max_p : an integer, the maximum desired size of a bucket. Default is the current threshold size. This must be 3 or higher.
  3. grow_p : an atom, the factor to grow the number of buckets for each iteration of rehashing. Default is 1.333. This must be greater than 1.
Comments:

This rehashes the map until either the maximum bucket size is less than the desired maximum or the maximum bucket size is less than the largest size statistically expected (mean + 3 standard deviations).

See Also:

statistics, rehash

8.32.4.28 load_map

include std/map.e
namespace map
public function load_map(object input_file_name)

Loads a map from a file

Parameters:
  1. file_name_p : The file to load from. This file may have been created by the save_map function. This can either be a name of a file or an already opened file handle.
Returns:

Either a map, with all the entries found in file_name_p, or -1 if the file failed to open, or -2 if the file is incorrectly formatted.

Comments:

If file_name_p is an already opened file handle, this routine will write to that file and not close it. Otherwise, the named file will be created and closed by this routine.

The input file can be either one created by the save_map function or a manually created/edited text file. See save_map for details about the required layout of the text file.

Example 1:
include std/error.e

object loaded
map AppOptions
sequence SavedMap = "c:\\myapp\\options.txt"

loaded = load_map(SavedMap)
if equal(loaded, -1) then
    crash("Map '%s' failed to open", SavedMap)
end if

-- By now we know that it was loaded and a new map created,
-- so we can assign it to a 'map' variable.
AppOptions = loaded
if get(AppOptions, "verbose", 1) = 3 then
    ShowIntructions()
end if
See Also:

new, save_map

8.32.4.29 SM_TEXT

include std/map.e
namespace map
public enum SM_TEXT

8.32.4.30 SM_RAW

include std/map.e
namespace map
public enum SM_RAW

8.32.4.31 save_map

include std/map.e
namespace map
public function save_map(map the_map_, object file_name_p, integer type_ = SM_TEXT)

Saves a map to a file.

Parameters:
  1. m : a map.
  2. file_name_p : Either a sequence, the name of the file to save to, or an open file handle as returned by open().
  3. type : an integer. SM_TEXT for a human-readable format (default), SM_RAW for a smaller and faster format, but not human-readable.
Returns:

An integer, the number of keys saved to the file, or -1 if the save failed.

Comments:

If file_name_p is an already opened file handle, this routine will write to that file and not close it. Otherwise, the named file will be created and closed by this routine.

The SM_TEXT type saves the map keys and values in a text format which can be read and edited by standard text editor. Each entry in the map is saved as a KEY/VALUE pair in the form

key = value
Note that if the 'key' value is a normal string value, it can be enclosed in double quotes. If it is not thus quoted, the first character of the key determines its Euphoria value type. A dash or digit implies an atom, an left-brace implies a sequence, an alphabetic character implies a text string that extends to the next equal '=' symbol, and anything else is ignored.

Note that if a line contains a double-dash, then all text from the double-dash to the end of the line will be ignored. This is so you can optionally add comments to the saved map. Also, any blank lines are ignored too.

All text after the '=' symbol is assumed to be the map item's value data.

Because some map data can be rather long, it is possible to split the text into multiple lines, which will be considered by load_map as a single logical line. If an line ends with a comma (,) or a dollar sign ($), then the next actual line is appended to the end of it. After all these physical lines have been joined into one logical line, all combinations of `",$"` and `,$` are removed.

For example:

one = {"first",
"second",
"third",
$
}
second = "A long text ",$
"line that has been",$
" split into three lines"
third = {"first",
"second",
"third"}
is equivalent to
one = {"first","second","third"}
second = "A long text line that has been split into three lines"
third = {"first","second","third"}

The SM_RAW type saves the map in an efficient manner. It is generally smaller than the text format and is faster to process, but it is not human readable and standard text editors can not be used to edit it. In this format, the file will

contain three serialized sequences:
  1. Header sequence: {integer:format version, string: date and time of save (YYMMDDhhmmss), sequence: euphoria version {major, minor, revision, patch}}
  2. Keys. A list of all the keys
  3. Values. A list of the corresponding values for the keys.
Example 1:
include std/error.e

map AppOptions
if save_map(AppOptions, 
    crash("Failed to save application options")
end if

if save_map(AppOptions, 
    crash("Failed to save application options")
end if
See Also:

load_map

8.32.4.32 copy

include std/map.e
namespace map
public function copy(map source_map, object dest_map = 0, integer put_operation = PUT)

Duplicates a map.

Parameters:
  1. source_map : map to copy from
  2. dest_map : optional, map to copy to
  3. put_operation : optional, operation to use when dest_map is used. The default is PUT.
Returns:

If dest_map was not provided, an exact duplicate of source_map otherwise dest_map, which does not have to be empty, is returned with the new values copied from source_map, according to the put_operation value.

Example 1:
map m1 = new()
put(m1, 1, "one")
put(m1, 2, "two")

map m2 = copy(m1)
printf(1, "%s, %s\n", { get(m2, 1), get(m2, 2) })
-- one, two

put(m1, 1, "one hundred")
printf(1, "%s, %s\n", { get(m1, 1), get(m1, 2) })
-- one hundred, two

printf(1, "%s, %s\n", { get(m2, 1), get(m2, 2) })
-- one, two
Example 2:
map m1 = new()
map m2 = new()

put(m1, 1, "one")
put(m1, 2, "two")
put(m2, 3, "three")

copy(m1, m2)

? keys(m2)
-- { 1, 2, 3 }
Example 3:
map m1 = new()
map m2 = new()

put(m1, "XY", 1)
put(m1, "AB", 2)
put(m2, "XY", 3)

pairs(m1) --> { {"AB", 2}, {"XY", 1} }
pairs(m2) --> { {"XY", 3} }

-- Add same keys' values.
copy(m1, m2, ADD)

pairs(m2) --> { {"AB", 2}, {"XY", 4} }
See Also:

put

8.32.4.33 new_from_kvpairs

include std/map.e
namespace map
public function new_from_kvpairs(sequence kv_pairs)

Converts a set of Key-Value pairs to a map.

Parameters:
  1. kv_pairs : A seqeuence containing any number of subsequences that have the format {KEY, VALUE}. These are loaded into a new map which is then returned by this function.
Returns:

A map, containing the data from kv_pairs

Example 1:
map m1 = new_from_kvpairs( {
    { "application", "Euphoria" },
    { "version", "4.0" },
    { "genre", "programming language" },
    { "crc", 0x4F71AE10 }
})

v = map:get(m1, "application") --> "Euphoria"

8.32.4.34 new_from_string

include std/map.e
namespace map
public function new_from_string(sequence kv_string)

Converts a set of Key-Value pairs contained in a string to a map.

Parameters:
  1. kv_string : A string containing any number of lines that have the format KEY=VALUE. These are loaded into a new map which is then returned by this function.
Returns:

A map, containing the data from kv_string

Comment:

This function actually calls keyvalues() to convert the string to key-value pairs, which are then used to create the map.

Example 1:

Given that a file called "xyz.config" contains the lines ...

application = Euphoria,
version     = 4.0,
genre       = "programming language",
crc         = 4F71AE10
map m1 = new_from_string( read_file("xyz.config", TEXT_MODE))

printf(1, "%s\n", {map:get(m1, "application")}) --> "Euphoria"
printf(1, "%s\n", {map:get(m1, "genre")})       --> "programming language"
printf(1, "%s\n", {map:get(m1, "version")})     --> "4.0"
printf(1, "%s\n", {map:get(m1, "crc")})         --> "4F71AE10"  

8.32.4.35 for_each

include std/map.e
namespace map
public function for_each(map source_map, integer user_rid, object user_data = 0,
        integer in_sorted_order = 0, integer signal_boundary = 0)

Calls a user-defined routine for each of the items in a map.

Parameters:
  1. source_map : The map containing the data to process
  2. user_rid: The routine_id of a user defined processing function
  3. user_data: An object. Optional. This is passed, unchanged to each call of the user defined routine. By default, zero (0) is used.
  4. in_sorted_order: An integer. Optional. If non-zero the items in the map are processed in ascending key sequence otherwise the order is undefined. By default they are not sorted.
  5. signal_boundary: A integer; 0 (the default) means that the user routine is not called if the map is empty and when the last item is passed to the user routine, the Progress Code is not negative.
Returns:

An integer: 0 means that all the items were processed, and anything else is whatever was returned by the user routine to abort the for_each() process.

Comment:
  • The user defined routine is a function that must accept four parameters.
    1. Object: an Item Key
    2. Object: an Item Value
    3. Object: The user_data value. This is never used by for_each() itself, merely passed to the user routine.
    4. Integer: Progress code.
      • The abs() value of the progress code is the ordinal call number. That is 1 means the first call, 2 means the second call, etc ...
      • If the progress code is negative, it is also the last call to the routine.
      • If the progress code is zero, it means that the map is empty and thus the item key and value cannot be used.
      • note that if signal_boundary is zero, the Progress Code is never less than 1.
  • The user routine must return 0 to get the next map item. Anything else will cause for_each() to stop running, and is returned to whatever called for_each().
  • Note that any changes that the user routine makes to the map do not affect the order or number of times the routine is called. for_each() takes a copy of the map keys and data before the first call to the user routine and uses the copied data to call the user routine.
Example 1:
include std/map.e
include std/math.e
include std/io.e

function Process_A(object k, object v, object d, integer pc)
    writefln("[] = []", {k, v})
    return 0
end function

function Process_B(object k, object v, object d, integer pc)
    if pc = 0 then
      writefln("The map is empty")
    else
      integer c
      c = abs(pc)
      if c = 1 then
          writefln("---[]---", {d}) -- Write the report title.
      end if
      writefln("[]: [:15] = []", {c, k, v})
      if pc < 0 then
          writefln(repeat('-', length(d) + 6), {}) -- Write the report end.
      end if
    end if
    return 0
end function

map m1 = new()
map:put(m1, "application", "Euphoria")
map:put(m1, "version", "4.0")
map:put(m1, "genre", "programming language")
map:put(m1, "crc", "4F71AE10")

-- Unsorted 
map:for_each(m1, routine_id("Process_A"))
-- Sorted
map:for_each(m1, routine_id("Process_B"), "List of Items", 1)  

The output from the first call could be...

application = Euphoria
version = 4.0
genre = programming language
crc = 4F71AE10

The output from the second call should be...

---List of Items---
1: application     = Euphoria
2: crc             = 4F71AE10
3: genre           = programming language
4: version         = 4.0
-------------------