In Haxe, Map
(also known as dictionary) allows key to value mapping for arbitrary value types and many key types.
To use a map you can use the convenient Map
abstract class in the toplevel
package, which automatically instantiates a specialized map based on the type parameters:
Map | Key type | Specialized map used |
---|---|---|
Map<String, V> | String | haxe.ds.StringMap |
Map<Int, V> | Int | haxe.ds.IntMap |
Map<EnumValue, V> | EnumValue | haxe.ds.EnumValueMap |
Map<MyType, V> | class or structure | haxe.ds.ObjectMap |
Map<Dynamic, V> | dynamic type | compile-time error |
The type of the value V
can be any other type. All the specialized maps can ofcourse be used directly and have the same functionalities, but the underlying implementations are different for optimal performance.
Map
however provides some features which the concrete types don't have which is explained later.
The specialized maps can be found in the haxe.ds
package.
Create a Map / Setting values
Since Map
is the easiest to work with, we'll use it in this article and start with creating a map with strings as keys and integers as values.
If you are using Map
you can use array access to set values map[key] = value
, otherwise you have to use map.set(key, value)
. Another reason to use Map
as much as possible.
var ageByUser = new Map<String, Int>(); ageByUser["John"] = 26; ageByUser["Peter"] = 17; ageByUser["Mark"] = 32;
This is the same as writing:
var ageByUser = new StringMap<Int>(); ageByUser.set("John", 26); ageByUser.set("Peter", 17); ageByUser.set("Mark", 32);
The naming convention of the map variable is "meaning of value by meaning of key".
A different way to create a map with values directly is by using a map literal ([key1 => value1, key2 => value2]
):
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ];
To give a quick visual of what we've just created above, this would be the data of our ageByUser
map:
Key user | Value age |
---|---|
John | 26 |
Peter | 17 |
Mark | 32 |
Retrieving values
Now we know how to create a map and set values, let's get a value and trace it:
As explained earlier, if you are using Map
you can use array access to get values map[key]
, otherwise you have to use map.get(key)
.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; var ageOfMark = ageByUser["Mark"]; trace(ageOfMark); // output: 32 // same as: var ageOfMark = ageByUser.get("Mark"); trace(ageOfMark); // output: 32
If the user "Mark" wouldn't exist in the map, the variable ageOfMark
would be null
. To be absolute sure if a certain key exists, you can check it using the map.exists
function.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; // Search for the user "Simon", which isn't defined in our map and trace its age. var user = "Simon"; if (ageByUser.exists(user)) { var age = ageByUser[user]; trace('$user is $age years old'); } else { trace('$user is not found'); }
Removing values
You can remove values using the map.remove
function.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; var user = "John"; ageByUser.remove(user); // double check trace(ageByUser.exists(user)); // false trace(ageByUser.get(user)); // null
Iteration
To iterate over all values of the map, use for (value in map)
.
In our example the values are defining the user's age, let's trace all ages.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; for (age in ageByUser) { trace(age); }
To iterate over the keys of the map, use for (key in map.keys())
.
In our example the keys are user names, let's trace all names.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; for (user in ageByUser.keys()) { trace(user); }
Of course this can be combined, let's trace the user and its age:
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; for (user in ageByUser.keys()) { var age = ageByUser[user]; trace('$user is $age years old'); }
Since Haxe 4.0 you can simplify the iteration on maps using the key-value iterator syntax for (key => value in map)
.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; for (user => age in ageByUser) { trace('$user is $age years old'); }
The order of both values and keys in any type of map is undefined, therefore you shouldn't rely it. If order is important (when the map needs to be sorted for example), convert it to an Array. This can be easily done with
Lamba.array(map)
to get the values as Array orvar keys = [for(key in map.keys()) key]
if you want the keys as Array.
Clear map
You can remove clear a map by iterating on all keys, and call remove from there.
var ageByUser = [ "John" => 26, "Peter" => 17, "Mark" => 32, ]; // clear map for (user in ageByUser.keys()) { ageByUser.remove(user); }
More information: