如何生成从集合中挑选的n个唯一元素的列表?

bug*_*oot 4 testing scala unique scalacheck

如何使用ScalaCheck从一组值(而不是生成器)生成n个唯一值(Gen[List[T]])的列表?这篇文章使用Gen[T]*而不是一组值,我似乎无法重写它以使其工作.

编辑

在@Jubobs的要求下,我现在可耻地展示了我到目前为止所做的一切,揭示了我在使用ScalaCheck时的全新状态:-)

我只是试图取代gs: Gen[T]重复参数到Set什么@Eric写的解决方案在这里:

def permute[T](n: Int, gs: Set[T]): Gen[Seq[T]] = {
    val perm = Random.shuffle(gs.toList)
    for {
        is <- Gen.pick(n, 1 until gs.size)
        xs <- Gen.sequence[List[T], T](is.toList.map(perm(_)))
    } yield xs
}
Run Code Online (Sandbox Code Playgroud)

但是is.toList.map(perm(_))用红色强调,IntelliJ IDEA告诉我"你应该在盲目(虽然直观)试验和错误之前首先阅读ScalaCheck API",或者"类型不匹配,预期:Traversable [Gen [T]],实际列表[T ]",我不记得了.

我还尝试了其他几种方法,其中大多数我觉得很荒谬(因而不值得发布),最天真的是使用@Eric的(其他有用和整洁的)解决方案:

val g = for (i1 <- Gen.choose(0, myList1.length - 1); 
  i2 <- Gen.choose(0, myList2.length - 1)) 
  yield new MyObject(myList1(i1), myList2(i2))
val pleaseNoDuplicatesPlease = permute(4, g, g, g, g, g)
Run Code Online (Sandbox Code Playgroud)

经过一些测试后,我发现pleaseNoDuplicatesPlease实际上包含重复项,此时我权衡了我必须阅读ScalaCheck API并理解了比现在更多的东西(这将不可避免地,并且逐渐到来),或者在我的问题上发布我的问题. StackOverflow(仔细搜索是否存在类似问题).

jub*_*0bs 6

Gen.pick 就在你的小巷里:

scala> import org.scalacheck.Gen
import org.scalacheck.Gen

scala> val set = Set(1,2,3,4,5,6)
set: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 3, 4)

scala> val myGen = Gen.pick(5, set).map { _.toList }
myGen: org.scalacheck.Gen[scala.collection.immutable.List[Int]] = org.scalacheck.Gen$$anon$3@78693eee

scala> myGen.sample
res0: Option[scala.collection.immutable.List[Int]] = Some(List(5, 6, 2, 3, 4))

scala> myGen.sample
res1: Option[scala.collection.immutable.List[Int] = Some(List(1, 6, 2, 3, 4))
Run Code Online (Sandbox Code Playgroud)

  • 还有一些选项:https://github.com/rickynils/scalacheck/blob/master/src/main/scala/org/scalacheck/Gen.scala#L651-L699`oneOf`将选择1,` someOf`将选择0-n,`atLeastOne`将选择1-n,而`pick`将选择您指定的任何数字. (2认同)