Ordered Multi-Map ORDMAPM

Added October 2016

Collection type ORDMAPM is equivalent to ORDMAP except it supports multiple keys of the same value. This structure is typically known as an ordered multi-map but we went with ORDMAPM instead ORDMMAP or ORDMULMAP or ORDMULTIMAP because it seemed easier to read and type.

As with the standard ORDMAP, ORDMAPM collections are declared with the DIMX statement and support the same two variations, one with a variable length string value, the other with a variable length binary/blob value; both with a variable length string key:

DIMX $mymap, ORDMAPM(varstr;varstr)

dimx $mymap, ordmapm(varstr;varx)

 

Note that are no promises regarding the internal order of elements with the same key, nor of which of those elements will be the one returned when retrieving an element by key. However, iterating through the entire array will return all of the elements. In addition, iterating from a specific key will also return all of the matches for that key.

For example:

dimx $MM, ORDMAPM(varstr;varstr)

...

foreach $$i in $MM(key$)   ! will iterate through all of the elements

....                       ! matching key$, followed by all of the

next $$i                   ! elements after key$

 

Here is a more complete example illustrating adding, iterating and deleting multiple entries for the same key:

! ordmapm example - adding and deleting elements

 

dimx $mm, ordmapm(varstr;varstr)

 

map1 key1$,s,0,"one"

map1 count,b,4

 

$mm(key1$) = "1"        ! three elements with same key

$mm(key1$) = "uno"

$mm(key1$) = "ein"

 

foreach $$i in $mm()

    ? .key($$i);" --> ";$$i

next $$i

 

? "Deleting all $mm(";key1$;")...";

count = fn'delmapm($mm(), key1$)

? count; "elements deleted"

 

if .isnull($mm(key1$)) then

    ? "Confirmed: all $mm(";key1$;") deleted."

else

    ? "Error: $mm(";key1$;") still exists: ";$mm(key1$)

endif

 

end

 

!---------------------------------------------------------------------

!Function:

!   delete all elements from ordmapm matching specified key

!Params:

!   $map()  (ordmapm(varstr;varstr) [byref] - map to delete from

!   key$    (str) [in] - key to delete

!Returns:

!   # deleted

!---------------------------------------------------------------------

function fn'delmapm($map() as ordmapm(varstr;varstr), key$ as s0) as b4

    do while not .isnull($map(key$))

        fn'delmapm += 1

        $map(key$) = .NULL

    loop

endfunction

 

History

2016 August, A-Shell 6.3.1520:  Add capability to A-Shell.