

In many applications it becomes necessary to look up a Record, Object or other data structure by a unique identifier, just as a phone book enables one look up a person's phone number by their name. This structure goes by many names: hashtable, lookup table, hashmap, dict, dictionary, map, etc. There are many tools for this in ReasonML, but two good choices are:
Map from Reason's OCaml standard API.
This is a good general-purpose, performant, immutable dictionary and should probably be
the first choice. Js.Dict.t.
This is is a thin wrapper over the mutable Javascript object.
It's a good option you are worried about minimizing your bundle size or
are modifying objects that come from JS. If you go to the Reason docs and search
for Map today, you won't find any resources for Map. There are many
features in Reason that are supplied by OCaml's standard
library, whose docs are accessible on the API tab of the Reason site,
though certain elements of the standard API are not currently indexed
by the search engine or given much coverage in the standard Reason docs.
If you look in the API tab, you'll find Map - Association tables over ordered types is one of API entries,
but the API docs can be a little sparse. In cases like this I find it helpful
to search for the item in Real World OCaml book or in Stack Overflow's OCaml posts,
and then use the Reason Tools browser extension
to convert any examples to Reason. See the Links section at the bottom of this post
for more information.
Map From a ListThis example declares a new Record type
called composer, then constructs a new Map type with String instances
as the lookup keys. After we have minted a specialized StringMap Module,
we create a getComposerMap function which converts a list of composer types
into the StringMap. See the post on Modules
in Gradus Reason for more info.
/* loading */This example is powered by:
String,
the String module from the Reason OCaml standard API, which is
a Module that operates on entities of the string
type. List.fold_left, which is
The Reason equivalent of Javascript's Array.prototype.reduce.
This iterates over an object and accumulates results into another object.
Here, we pass the function that will be applied to each element of the list:
(map, user) => StringMap.add(user.id, user.name, map). This function that we supply
itself takes two parameters. The first parameter (here, map) is the variable
to accumulate results in. The second parameter (here, user) is the current object
in the iteration:
List.fold_left(
(map, user) => StringMap.add(user.id, user.name, map),
StringMap.empty,
composers
)This takes the composers array, which is a list of composer types,
and executes the supplied folding function (map, user) => StringMap.add(user.id, user.name, map).
For the first composer, map is StringMap.empty. For all the other
composers, the map parameter is the cumulative result of calling
StringMap.add(user.id, user.name, map). At the end of fold_left, the last
composer returns the newly filled StringMap.
j string interpolation, which
looks like {j|key:$id, val:$composerName|j} and is the equivalent of JS' string interpolation. Here, the
$id and $composerName variables are resolved from block scope into a string.module StringMap = Map.Make(String);, that constructed
a new, specific instance of the Map Module that has String map keys.
You could think of Map.Make as a constructor for a Module, and the
constructed module has the same methods listed in the documentation.MapMap.MakeMapsMap vs Js.Dict.tList.fold_left is
the Reason equivalent to JS' Array.reduce.
Here's a Codepen - ES6 + array.reduceImage Credit: Warburton Post Office Boxes by Mick Stanic on Flickr