问题描述
我对 ScalaCheck 还很陌生,不知何故我想生成一个不同值的列表(即一个集合)。按照我的方法,这些值并不是唯一的。
val valueList: Gen[List[Int]] = Gen.listof(Arbitrary.arbitrary[Int])
创建具有唯一值/集合的列表的可能方法是什么?也许使用 suchThat
或 distinct
?
解决方法
粗略但有效:
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])