# Maps

In use, maps are similar to Lists in that they can store a varying number of elements that are accessed by a value.

They differ in several ways. Map data types act as a lookup from one value (the key) to another. Values used as a key are not restricted to integers and do not have to be sequential. Keys and values can be of any valid FISH type. Like lists, maps are passed by value. Lastly, maps are dynamically sized.

See the Map Utilities for available methods that exist to create and manipulate map types.

Map types are created using the map intrinsic, as follows.

map1 = map


Maps can be assigned entries during creation by providing key/value pairs to the map intrinsic.

map1 = map(10,1.0,   'fred',4.0,   3.4,6.0)


The line above creates a map with three key/value pairs, one that maps the integer 10 to the value 1.0, one that maps the string fred to the value 4.0, and one that maps the real value 3.4 to the value 6.0.

Accessing a value given a key is done using the () operator, just like arrays.

v = map1('fred')


The line above returns the value 4.0 that was assigned to the key fred. Maps are implemented using a generalized sorted red-black tree container to optimize lookup times.

You can iterate through all the values of a map using the loop foreach statement. This will assign the loop variable sequentially to every value of the map.

loop foreach local v map1
io.out(v)
endloop


You can also iterate through the keys of a map by using the map.keys intrinsic:

loop foreach local v map.keys(map1)
io.out(string(v) + ' = ' + string(map1(v)))
endloop


Because maps are passed by value, assigning a map to another symbol creates a copy of the map, rather than having both symbols refer to the same array. For example,

local a = map(1,'fred',    5,'george')
local b = a
b(5) = 'mary'
io.out(a(5))
io.out(b(5))


will output ‘george’ then ‘mary’.

The following data file offers further examples of the use of maps in FISH.

fish define testBreak
loop local i (1,2)
testmap = map('first',1,  'second',2,  'third',3)
sum = 0
loop foreach local v testmap
sum = sum + v
endloop
endloop
end
[testBreak]
[sum]

fish define test1
local temp = map('hello',1,'world',2)
test1 = temp('hello') + temp('world')
end
[test1]

fish define test2
testmap = map('first',1,'second',2,'third',3)
map.remove(testmap,'first')
testmap('second')=8
; values are now fourth->4, second->8, third->3
local output = 0
loop foreach n testmap
output = output + n
endloop
test2 = output
end
[test2]

fish define test3
; test keys
testmap = map('yet',1,'another',4,'test',9,'m',16)
testkeys = map.keys(testmap)
test3 = testkeys(3)

; check has
if (map.has(testmap,'wrongkey'))
hascheck = 909
else if (map.has(testmap,'another'))
hascheck = testmap('another')
endif
end
[test3]
[hascheck]


Maps are an iterable type. This means you can use it as the target of a loop foreach statement (see Loop ForEach and can be split (see Splitting). Each value of the map is iterated through in order.

As with most aggregate types, when the value is listed it will simply indicate that it is of type Map and the the number of entries. To see the contents of the map use the fish list contents command.