Skip to main content
Version: 2.x

TMap

A TMap[A] is a mutable map that can participate in transactions in STM.

Create a TMap

Creating an empty TMap:

import zio._
import zio.stm._

val emptyTMap: STM[Nothing, TMap[String, Int]] = TMap.empty[String, Int]

Or creating a TMap with specified values:

import zio._
import zio.stm._

val specifiedValuesTMap: STM[Nothing, TMap[String, Int]] = TMap.make(("a", 1), ("b", 2), ("c", 3))

Alternatively, you can create a TMap by providing a collection of tuple values:

import zio._
import zio.stm._

val iterableTMap: STM[Nothing, TMap[String, Int]] = TMap.fromIterable(List(("a", 1), ("b", 2), ("c", 3)))

Put a key-value pair to a TMap

New key-value pair can be added to the map in the following way:

import zio._
import zio.stm._

val putElem: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2))
_ <- tMap.put("c", 3)
} yield tMap).commit

Another way of adding an entry in the map is by using merge:

import zio._
import zio.stm._

val mergeElem: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.merge("c", 4)((x, y) => x * y)
} yield tMap).commit

If the key is not present in the map it behaves as a simple put method. It merges the existing value with the new one using the provided function otherwise.

Remove an element from a TMap

The simplest way to remove a key-value pair from TMap is using delete method that takes key:

import zio._
import zio.stm._

val deleteElem: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.delete("b")
} yield tMap).commit

Also, it is possible to remove every key-value pairs that satisfy provided predicate:

import zio._
import zio.stm._

val removedEvenValues: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3), ("d", 4))
_ <- tMap.removeIf((_, v) => v % 2 == 0)
} yield tMap).commit

Or you can keep all key-value pairs that match predicate function:

import zio._
import zio.stm._

val retainedEvenValues: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3), ("d", 4))
_ <- tMap.retainIf((_, v) => v % 2 == 0)
} yield tMap).commit

Note that retainIf and removeIf serve the same purpose as filter and filterNot. The reason for naming them differently was to emphasize a distinction in their nature. Namely, both retainIf and removeIf are destructive - calling them can modify the collection.

Retrieve the value from a TMap

Value associated with the key can be obtained as follows:

import zio._
import zio.stm._

val elemGet: UIO[Option[Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
elem <- tMap.get("c")
} yield elem).commit

Alternatively, you can provide a default value if entry by key is not present in the map:

import zio._
import zio.stm._

val elemGetOrElse: UIO[Int] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
elem <- tMap.getOrElse("d", 4)
} yield elem).commit

Transform entries of a TMap

The transform function (K, V) => (K, V) allows computing a new value for every entry in the map:

import zio._
import zio.stm._

val transformTMap: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.transform((k, v) => k -> v * v)
} yield tMap).commit

Note that it is possible to shrink a TMap:

import zio._
import zio.stm._

val shrinkTMap: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.transform((_, v) => "d" -> v)
} yield tMap).commit

The entries can be mapped effectfully via transformSTM:

import zio._
import zio.stm._

val transformSTMTMap: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.transformSTM((k, v) => STM.succeed(k -> v * v))
} yield tMap).commit

The transformValues function V => V allows computing a new value for every value in the map:

import zio._
import zio.stm._

val transformValuesTMap: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.transformValues(v => v * v)
} yield tMap).commit

The values can be mapped effectfully via transformValuesSTM:

import zio._
import zio.stm._

val transformValuesMTMap: UIO[TMap[String, Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
_ <- tMap.transformValuesSTM(v => STM.succeed(v * v))
} yield tMap).commit

Note that both transform and transformValues serve the same purpose as map and mapValues. The reason for naming them differently was to emphasize a distinction in their nature. Namely, both transform and transformValues are destructive - calling them can modify the collection.

Folds the elements of a TMap using the specified associative binary operator:

import zio._
import zio.stm._

val foldTMap: UIO[Int] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
sum <- tMap.fold(0) { case (acc, (_, v)) => acc + v }
} yield sum).commit

The elements can be folded effectfully via foldSTM:

import zio._
import zio.stm._

val foldSTMTMap: UIO[Int] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
sum <- tMap.foldSTM(0) { case (acc, (_, v)) => STM.succeed(acc + v) }
} yield sum).commit

Perform effects for TMap key-value pairs

foreach is used for performing an STM effect for each key-value pair in the map:

import zio._
import zio.stm._

val foreachTMap = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
tQueue <- TQueue.unbounded[String]
_ <- tMap.foreach((k, v) => tQueue.offer(s"$k -> $v").unit)
} yield tMap).commit

Check TMap membership

Checking whether key-value pair is present in a TMap:

import zio._
import zio.stm._

val tMapContainsValue: UIO[Boolean] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
res <- tMap.contains("a")
} yield res).commit

Convert TMap to a List

List of tuples can be obtained as follows:

import zio._
import zio.stm._

val tMapTuplesList: UIO[List[(String, Int)]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
list <- tMap.toList
} yield list).commit

List of keys can be obtained as follows:

import zio._
import zio.stm._

val tMapKeysList: UIO[List[String]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
list <- tMap.keys
} yield list).commit

List of values can be obtained as follows:

import zio._
import zio.stm._

val tMapValuesList: UIO[List[Int]] = (for {
tMap <- TMap.make(("a", 1), ("b", 2), ("c", 3))
list <- tMap.values
} yield list).commit