问题描述
我有一些这样的生成器:
I have some generators like this:
val fooRepr = oneOf(a, b, c, d, e)
val foo = for (s <- choose(1, 5); c <- listOfN(s, fooRepr)) yield c.mkString("$")
这会导致重复...我可能会得到两个a,以此类推.我真正想要的是生成正好为0或1或a,b,c,d或e(至少有一个)的随机排列的东西),以任何顺序.
This leads to duplicates ... I might get two a's, etc. What I really want is to generate random permutation with exactly 0 or 1 or each of a, b, c, d, or e (with at least one of something), in any order.
我本以为必须有一种简单的方法,但我一直在努力寻找困难的方法. :)
I was thinking there must be an easy way, but I'm struggling to even find a hard way. :)
好的,这似乎可行:
val foo = for (s <- choose(1, 5);
c <- permute(s, a, b, c, d, e)) yield c.mkString("$")
def permute[T](n: Int, gs: Gen[T]*): Gen[Seq[T]] = {
val perm = Random.shuffle(gs.toList)
for {
is <- pick(n, 1 until gs.size)
xs <- sequence[List,T](is.toList.map(perm(_)))
} yield xs
}
...从Gen.pick
大量借贷.
感谢您的帮助-Eric
Thanks for your help, -Eric
推荐答案
Rex,感谢您明确说明了我要执行的操作,这是有用的代码,但是对scalacheck来说可能不太好,尤其是在涉及到生成器的情况下非常复杂.在我的特定情况下,生成器a,b,c等正在生成巨大的字符串.
Rex, thanks for clarifying exactly what I'm trying to do, and that's useful code, but perhaps not so nice with scalacheck, particularly if the generators in question are quite complex. In my particular case the generators a, b, c, etc. are generating huge strings.
无论如何,以上我的解决方案中存在一个错误;为我工作的是下面.我在 github
Anyhow, there was a bug in my solution above; what worked for me is below. I put a tiny project demonstrating how to do this at github
它的胆量在下面.如果有更好的方法,我很想知道...
The guts of it is below. If there's a better way, I'd love to know it...
package powerset
import org.scalacheck._
import org.scalacheck.Gen._
import org.scalacheck.Gen
import scala.util.Random
object PowersetPermutations extends Properties("PowersetPermutations") {
def a: Gen[String] = value("a")
def b: Gen[String] = value("b")
def c: Gen[String] = value("c")
def d: Gen[String] = value("d")
def e: Gen[String] = value("e")
val foo = for (s <- choose(1, 5);
c <- permute(s, a, b, c, d, e)) yield c.mkString
def permute[T](n: Int, gs: Gen[T]*): Gen[Seq[T]] = {
val perm = Random.shuffle(gs.toList)
for {
is <- pick(n, 0 until gs.size)
xs <- sequence[List, T](is.toList.map(perm(_)))
} yield xs
}
implicit def arbString: Arbitrary[String] = Arbitrary(foo)
property("powerset") = Prop.forAll {
a: String => println(a); true
}
}
谢谢,埃里克
这篇关于使用scalacheck生成排列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!