TSet[A]
是一个可以参与 STM 中事务可变集合。
创建一个 TSet
创建一个空的 TSet
:
import zio._
import zio.stm._
val emptyTSet: STM[Nothing, TSet[Int]] = TSet.empty[Int]
或创建具有指定值的 TSet
:
import zio._
import zio.stm._
val specifiedValuesTSet: STM[Nothing, TSet[Int]] = TSet.make(1, 2, 3)
或者,您可以通过具有值的集合来创建 TSet
:
import zio._
import zio.stm._
val iterableTSet: STM[Nothing, TSet[Int]] = TSet.fromIterable(List(1, 2, 3))
如果提供了重复项,则取最后一个。
将一个值加入 TSet
可以通过以下方式将新元素添加到集合中:
import zio._
import zio.stm._
val putElem: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2)
_ <- tSet.put(3)
} yield tSet).commit
如果集合已经包含元素,则不会进行任何修改。
从 TSet 中删除元素
从 TSet
中删除元素的最简单方法是使用 delete
函数:
import zio._
import zio.stm._
val deleteElem: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3)
_ <- tSet.delete(1)
} yield tSet).commit
同样,可以删除满足所提供函数参数的每个元素:
import zio._
import zio.stm._
val removedEvenElems: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.removeIf(_ % 2 == 0)
} yield tSet).commit
或者,您可以保留所有与函数参数相匹配的元素:
import zio._
import zio.stm._
val retainedEvenElems: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.retainIf(_ % 2 == 0)
} yield tSet).commit
请注意,retainIf
和 removeIf
与 filter
和 filterNot
具有相同的目的。分别命名它们的原因是要强调其本质上的区别。也就是说,retainIf
和 removeIf
都是破坏性的,调用它们会修改集合本身。
TSet 的并集
Set A 和 Set B 的并集表示属于 Set A 或 Set B 或两者都属于的元素集。使用 A union B
函数来修改 A 集合(取得两者的并集)。
import zio._
import zio.stm._
// unionTSet = {1, 2, 3, 4, 5, 6}
val unionTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.union(tSetB)
} yield tSetA).commit
TSet 的交集
Set A 和 Set B 的交集指的是同时属于 A 和 B 的元素集。使用 A intersect B
函数修改 A 集合(来取得交集)。
import zio._
import zio.stm._
// intersectionTSet = {3, 4}
val intersectionTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.intersect(tSetB)
} yield tSetA).commit
TSet 的差集
Set A 和 Set B 的差集是包含于集合 A但,集合 B 中没有元素。使用 A diff B
函数来获得。The difference between sets A and B is the set containing elements of set A but not in B. Using A diff B
method modifies set A
.
import zio._
import zio.stm._
// diffTSet = {1, 2}
val diffTSet: UIO[TSet[Int]] = (for {
tSetA <- TSet.make(1, 2, 3, 4)
tSetB <- TSet.make(3, 4, 5, 6)
_ <- tSetA.diff(tSetB)
} yield tSetA).commit
转换 TSet 的元素
transform(A => A)
函数允许基于集合中的每个元素计算一个新值:
import zio._
import zio.stm._
val transformTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transform(a => a * a)
} yield tSet).commit
以下可以压缩 TSet:
import zio._
import zio.stm._
val shrinkTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transform(_ => 1)
} yield tSet).commit
上面示例得到的结果集只有一个元素。
请注意,transform
的作用与 map
相同。对其进行不同命名的原因是要强调其本质上的区别。也就是说,transform
是破坏性的,调用它会修改集合本身。
可以通过 transformM 效果化地映射元素:
import zio._
import zio.stm._
val transformMTSet: UIO[TSet[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.transformM(a => STM.succeed(a * a))
} yield tSet).commit
fold
可以使用指定的二元运算折叠 TSet
的元素:
import zio._
import zio.stm._
val foldTSet: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
sum <- tSet.fold(0)(_ + _)
} yield sum).commit
元素可以通过 foldM 有效折叠:The elements can be folded effectfully via foldM
:
import zio._
import zio.stm._
val foldMTSet: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
sum <- tSet.foldM(0)((acc, el) => STM.succeed(acc + el))
} yield sum).commit
对 TSet 中的元素执行side-effect
foreach
用于对集合中的每个元素执行副作用:
import zio._
import zio.stm._
val foreachTSet = (for {
tSet <- TSet.make(1, 2, 3, 4)
_ <- tSet.foreach(a => STM.succeed(println(a)))
} yield tSet).commit
检查 TSet 的成员
检查元素是否存在于 TSet
中:
import zio._
import zio.stm._
val tSetContainsElem: UIO[Boolean] = (for {
tSet <- TSet.make(1, 2, 3, 4)
res <- tSet.contains(3)
} yield res).commit
将 TSet 转换为 List
可以按以下方式获取集合元素的列表:
import zio._
import zio.stm._
val tSetToList: UIO[List[Int]] = (for {
tSet <- TSet.make(1, 2, 3, 4)
list <- tSet.toList
} yield list).commit
TSet 的大小
集的大小可以通过以下方式获得:
import zio._
import zio.stm._
val tSetSize: UIO[Int] = (for {
tSet <- TSet.make(1, 2, 3, 4)
size <- tSet.size
} yield size).commit