ScalaCheck 生成不同的值列表

问题描述

我对 ScalaCheck 还很陌生,不知何故我想生成一个不同值的列表(即一个集合)。按照我的方法,这些值并不是唯一的。

val valueList: Gen[List[Int]] = Gen.listof(Arbitrary.arbitrary[Int])

创建具有唯一值/集合的列表的可能方法是什么?也许使用 suchThatdistinct

解决方法

粗略但有效:

Gen.listOf(Arbitrary.arbitrary[Int]).map(_.toSet)

如果你想要一组特定尺寸的,你可以做类似的事情

def setOfN[A](n: Int,gen: Gen[A]): Gen[Set[A]] =
  Gen.listOfN(n,gen).flatMap { lst =>
    val set = lst.toSet

    if (set.size == n) Gen.const(set)
    else if (set.size > n) Gen.const(set.take(n))
    else setOfN(n - set.size,gen.retryUntil(x => !set(x))).flatMap(_ ++ set)
  }

(值得注意的是,retryUntil 可能很脆弱,特别是当 n 相对于常见生成值的数量增长时(例如,对于 Int,Scalacheck 相当频繁地生成 0、+/- 1 等))>

当然,因为 org.scalacheck.util.Buildable 有一个 Set 实例

Gen.containerOf[Set,Int](Arbitrary.arbitrary[Int])