« Back to University of Vienna - OMILAB

RE: Working with map in AdoScript

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Working with map in AdoScript
Answer
6/13/14 11:56 AM
Dear All,

I am currently in the situation where I would like to work with a map data structure (key-value pairs).
Unfortunately, the ADOxx help does not provide adequate support in explaining the functions to add/deldete/serach/iterate a map.
It would be very nice, if you could provide me/the community with some more details about the map data structure and the functionality prvodided by ADOxx/AdoScript to work with maps.

Thank you very much in advance.

RE: Working with map in AdoScript
Answer
6/13/14 6:21 PM as a reply to Anonymous.
Thank you for your interesting question and feedback on the documentation section of ADOxx. We are continously updating and enhancing the documentation pages and appreciate community feedback.

With respect to the map "concept" in ADOxx, please find below a detailled summary of the functionality provided by this data structure

1. Create a new empty map using AdoScript
1SETL mMap: (map())
2CC "AdoScript" INFOBOX ("This is the empty map: " + STR mMap)
A key and a related value are separated by a colon (":"), multiple key-value pairs are separated by comma (","), the set of pairs is enclosed in curly parentheses ("{" and "}").#
Important remark: As the colon character (":") is used for defining maps, a key (if of type string) must not contain such a character. If this is not respected, ADOxx will display an error message. Minding the colon character is especially relevant, if not fixed, but dynamic keys are used (e.g. object names).

2. Create/Initialize a map with key/value paris
1SETL mMap: ({ 1780: "Sim", 1920: "Sala", 2007: "Bim" })
2CC "AdoScript" INFOBOX ("This is the initial map: " + STR mMap)

3. Get the map length using m.length or LEN (m)
Length (size) of a map. m has to be of type map. The result is number of elements of m. Alternatively, LEN m can be used
1SETL nMapSize: (mMap.length)
2CC "AdoScript" INFOBOX ("The map has " + STR nMapSize + " entries.")

4. Check on empty map using m.empty
Returns 1 (true) if the map is empty and 0 (false) otherwise.
1SETL bIsEmpty: (mMap.empty)
2CC "AdoScript" INFOBOX ("The map is empty? " + STR bIsEmpty)

5. Remove map item by key using merase(m, k)
1SETL dummy: (merase (mMap, 1780))
2CC "AdoScript" INFOBOX ("After removal the map look like this: " + STR mMap)
The return of merase is the value of the deleted entry

6. Add item to map using subscription
1SETL mMap[2014]:"Bam"
2CC "AdoScript" INFOBOX ("Including the new item, the map look like this: " + STR mMap)

7. Retrieve value by key
Subscription to a map using SUB or []
m SUB k or m, where m has to be of type map, k of type string, integer, real, measure or time. The result is the element of m with key k. If the key is not contained in the map, the result is of type undefined.
Value elements of a map, and so the result of the subscription, may be of any type. The type of two different value elements of one map needs not to be the same. Use type() if you are not sure about a value element's type.
1SETL value: (mMap SUB 2014)
2CC "AdoScript" INFOBOX ("The value for key 2014: " + value)

8. Application of above concepts to realize a keyset iterator (assuming integer keys)
 1SETL sMap: (STR mMap)
 2SETL sMap: (replall(sMap, "{", ""))
 3SETL sMap: (replall(sMap, "}", ""))
 4SETL nTokenCount: (tokcnt (sMap, ","))
 5SETL aKeySet: (array(nTokenCount))FOR nCount from:0 to: (nTokenCount-1) by:1 {
 6  SETL aKeySet: (VAL (copy (token (sMap, nCount, ","), 0, search (token (sMap, nCount, ","), ":", 0))).trim())
 7}
 8CC "AdoScript" INFOBOX ("The keyset of the array looks like this: " + STR aKeySet)
 9# Iterate through map and return all values
10FOR nCount from:0 to: (aKeySet.length-1) by:1 {
11  SETL nKey: (aKeySet)
12  SETL sValue: (mMap)
13  CC "AdoScript" INFOBOX ("The current key is: " + STR nKey + "\nFor this key the value is: " + sValue)
14}
Please be aware that the above approach assumes integer keys and uses the ADOxx array concept to store the keyset. The functionality can be globally added to your implementation by adding an AdoScript FUNCTION

In addition to the above functionality, additional functionality is planned for an upcoming ADOxx platform release.

RE: Working with map in AdoScript
Answer
6/14/14 7:58 AM as a reply to Wilfrid Utz.
Thank you very much for the detailed answer!

RE: Working with map in AdoScript
adoscript
Answer
8/30/17 1:38 PM as a reply to Wilfrid Utz.
Dear Wilfrid,

thank you very much for the detailed description. Since I'm to lazy to always copy and adapt the code to get the "keyset iterator" I have implemented 2 functions that should do this for me.

The attached .asc file contains the functions as well as some comments with the details. I have tested the code a bit, but not extensively. Since they follow your solution for the determining the keyset they do not allow for "," or ":" in the keys or the values.
mapKeySet(myMap) - returns an array containing all the keys. It uses their correct type (i.e. integer keys are integers in the array and string keys are strings in the array).
mapKeySetStrings(myMap) - returns an "@" separated list (string) containing all the keys. This one works ONLY for maps where all the keys are strings. Because of that the entries in the list are also strings and not further encoded.

There is also a third function, that however seems to have a problem:
mapKeySet2(myMap) - returns an "@" separated list (string) containing all the keys. The entries in the list are stored to reflect their type (e.g. strings are surounded by ").
The function itself seems to work fine, however when I split the list into it's tokens and pass a token to the "eval(...)" function I get an asleo-84 error, but after that I apparently still the right value.

Best regards,
Patrik
Attachments: mapKeySetFunctions.asc (4.5k)

RE: Working with map in AdoScript
Answer
5/28/20 9:05 AM as a reply to Patrik.
Hello,

I decided to create an updated version of the "get keys from a map" functions, which you can find in the file attached to this post. It provides four global functions, which have fewer restrictions and are more precise than the previous version:

mapKeysArray(myMap) - returns an array containing all the keys. It uses their correct type (i.e. integer keys are integers in the array and string keys are strings in the array).
mapKeysTypes(myMap) - returns a whitespace (" ") separated list (string) containing all the types of the keys (whether all keys are of type string, whether they are a mix of string and integer, whether they are only integer keys etc.).
mapKeysList(myMap) - returns a "~" separated list (string) containing all the keys. This one works ONLY for maps where all the keys are strings. Because of that the entries in the list are also strings and not further encoded.
mapKeysTypedList(myMap) - returns a "~" separated list (string) containing all the keys. The entries in the list reflect their type (e.g. strings are surounded by double-quotes "). The actual values with the correct type can be obtained by using the eval(...) function.

Additional details can be found in the file as comments as well as some simple testing code.

Best regards,
Patrik
Attachments: mapKeySetFunctions_v2.asc (4.2k)