IStringMap interface

A string map object is an array of key-value pairs. A key is an unique string that is used to access the associated value. A value is a string that is associated with the key. Unlike a simple array, a string map is optimized to quickly find an item, even if there are 1000000 items. A string map, for example, can be used to store dictionary data in memory, where keys are words of language A, and values are words of language B. Also can be used to store a list of unique strings that are not necessary associated with values.

 

To create a string map object, use function CreateStringMap or _create (QM 2.3.4). To work with it, use IStringMap interface.

 

Example

 

IStringMap m._create
lpstr s=
 key1 value1
 key2 value2
 key3 value3
m.AddList(s)

lpstr v=m.Get("key2")
if(v) out v
else out "not found"

 

Global functions

 

dll "qm.exe" IStringMap'CreateStringMap flags ;;flags: 1 case insens., 2 exists - do nothing, 4 exists - replace, 8 exists - add new, 16 exists - compare

 

Creates string map object and returns IStringMap COM interface pointer.

 

flags - same as with function Flags, see below.

 

QM 2.3.4. You can instead use _create.

 

IStringMap member functions

Member functions are called like: variable.Function(arguments). See the example code at the top of this topic. Note that the colored code lines below are not function calling examples. They are copied from interface declaration and used here to show function name, arguments etc.

 


[p]Flags(flags) ;;1 case insens., 2 exists - do nothing, 4 exists - replace, 8 exists - add new, 16 exists - compare
[g]#Flags()

 

Sets or gets flags to change default behavior of other functions.

 

Error if map is not empty.

 

flags:

1 Case insensitive. For example, Get("a") will find key "a" or "A".
2, 4, 8, 16

What to do when Add, AddList or Rename tries to add a key that already exists.

Default Error.
2 Don't add the new key.
4 Replace old value (like Set).
8 Add new item. Then the map can have duplicate keys. By default, functions Get, Get2, Set, Rename and Remove will get first added key; functions GetAll, GetAllOf and EnumNext will retrieve identical keys in FIFO order. If flag 4 also is used - last added key, LIFO order.
16 Compare new and old value. If equal, do nothing. If different, see other flags.

Evaluation order: 16, 8, 4, 2.

 

Added in QM 2.3.4.

 

Example

IStringMap m._create; m.Flags=1

 


Add($k $v)

 

Adds item (key-value pair) to the map. Error if the key already exists, unless flags 2-16 used with Flags or CreateStringMap. v may be empty ("" or 0). If v is 0, is added "" instead.

 


AddList($s $sep)

 

Adds multiple items to the map. Error if a key from the list already exists in the map, unless flags 2-16 used with Flags or CreateStringMap. In the list, each line should contain a key-value pair. To separate key and value, use characters specified in sep. Default sep is " [9]" (spaces and tabs). Note that sep is not a separator string; it is a set of characters that can be used. If a line is empty or begins with a separator character, does not add it. If a line contains only key, value is "". If you want to add simple list of strings (keys without values), you can use "[]" as sep to avoid breaking strings into keys and values.

 

QM 2.3.3. If sep is "csv", interprets s as CSV string. For example, use CSV when items may be multiline. The 4-th character of sep sets separator. For example, "csv=" sets separator =. Default separator is comma. The CSV must contain 1 or 2 columns.

 


$Get($k)

 

Returns the value associated with the specified key. If the key does not exist, returns 0, and also sets _hresult to 1. Warning: the returned value is a lpstr that points to internal data, and therefore becomes invalid after you call a function that modifies the map. To avoid this, assign it to a str variable. Also, this function is not thread-safe, because another thread may call a function that modifies the map. This function is always safe if it is used just to check if the key exists (if(m.Get("key")) ...). Note: if the key exists but the value is empty (added "" or 0), this function returns "", which evaluates to true with if.

 


$Get2($k str&v)

 

Same as Get, but is always safe. Stores the value into the str variable v. Although this function is slightly slower than Get, use it if the map object can be modified by other threads.

 


Set($k $v)

 

Changes value. Error if the key does not exist.

 


Rename($k $newname)

 

Changes key name. Error if the key does not exist.

 


Remove($k)

 

Removes item (key and value). If the key does not exist, does not generate an error, but sets _hresult to 1.

 


RemoveAll()

 

Removes all items.

 


#Count()

 

Returns the number of items.

 


GetAll(ARRAY(str)&ak ARRAY(str)&av)

 

Retrieves all keys and/or values. Stores keys into str array ak, unless it is 0. Stores values into str array av, unless it is 0. Example:

 

ARRAY(str) ak av
m.GetAll(ak av)
int i
for(i 0 ak.len)
	out "%s %s" ak[i] av[i]

 


#GetAllOf($k ARRAY(str)&av)

 

Retrieves values of all keys that match k. Can be useful if the map is created with flag 8, which allows to add duplicate keys.

 

Returns the number of matching keys. If there are no matching keys, returns 0 and sets _hresult to 1.

 

av - variable that receives values. Can be 0 if don't need.

 


GetList(str&s $sep)

 

Writes all items to a str variable. Each line will contain a key-value pair. Key and value will be separated by sep. Default sep is " ".

 

QM 2.3.3. If sep is "csv", creates CSV string. For example, use CSV when items may be multiline. The 4-th character of sep sets separator. For example, "csv=" sets separator =. Default separator is comma. The CSV will contain 2 columns.

 


EnumBegin()

 

Begins to enumerate items.

 


#EnumNext(str&k str&v)

 

Retrieves next item. Returns 1 if successful, or 0 if there are no more items. Stores key into str variable sk, unless it is 0. Stores value into str variable sv, unless it is 0. Example:

 

str sk sv
m.EnumBegin
rep
	if(!m.EnumNext(sk sv)) break
	out "%s %s" sk sv

 


EnumEnd()

 

Should be called (although not necessary) if the enumeration loop exits before all items are enumerated.

 


IntAdd($k v)

 

Adds item. Same as Add, but v is integer number. Internally it is stored as string. To add a numeric value (including double and other types), also can be used Add, but you have to convert it to string (assign it to a str variable and pass the variable to Add). This function just simplifies that.

 


#IntGet($k int&v)

 

Gets value as integer number. If key exists, stores value into v and returns 1, else returns 0. To retrieve a numeric value also can be used other functions (Get, GetAll, etc). These functions return the number as string, and you can use val to convert it to number. This function just simplifies that.

 


IntSet($k v)

 

Changes value. Same as Set, but v is integer number.

 

Notes

To retrieve all items, can be used GetAll, GetList or EnumX functions. GetAll is slower and requires much memory to store all data, especially if the map is large. However, EnumX functions should not be called simultaneously in multiple threads. Items always are retrieved sorted.

 

All IStringMap functions are thread-safe, except in cases mentioned above. It means that a map object can be used by multiple threads simultaneously.

 

If a function generates an error, its description always is "The parameter is incorrect". The most common error is when you try to add an item that already exists. To avoid it, you can use Get to check if it exists, or use err (faster), or use flags 2-16 with Flags or CreateStringMap. Examples:

 

if(!m.Get("key2"))
	m.Add("key2" "new value")
else
	out "already exists"

m.Add("key2" "new value")
err
	out "already exists"