如何确保未选择相同的随机元素两次



我正在使用以下代码随机选择两个元素:

scala.util.Random.shuffle(myList).take(2)

如何确保未选择两个元素两次?

我可以从列表中删除随机元素,创建一个新列表,然后使用与上述相同的代码?

更多上下文会很好;就像在一样,为什么不将列表转换为更容易处理此任务的内容,例如迭代器或数组?

将其保留为列表,我看到了两个选项:

  1. 使用列表的长度从一系列索引中选择两个随机数,检查两个随机数是否不相同,然后从列表中拉出两个随机数。
  2. 取1,删除它,然后再拿另一个,而不是一次服用。

这足以使其洗一次。但是,如果您需要非辩护,则列表不得包含重复的条目。

import scala.util.Random
object shuffleList {
  val l = (1 to 13).toList //=> List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
  // shuffle once
  val shuf = Random.shuffle(l) //=> List(13, 11, 3, 5, 2, 7, 6, 9, 4, 10, 12, 1, 8)
  // iterate them grouped by interval of 2
  shuf.grouped(2).foreach(println)
                         // => List(13, 11)
                                              //| List(3, 5)
                                              //| List(2, 7)
                                              //| List(6, 9)
                                              //| List(4, 10)
                                              //| List(12, 1)
                                              //| List(8)
}

当原始列表具有重复项时:

val dl = List(1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13)
                                                  //> dl  : List[Int] = List(1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13)

  Random.shuffle(dl.toSet.toList).grouped(2).foreach(println)
                                                  //> List(7, 3)
                                                  //| List(1, 11)
                                                  //| List(13, 8)
                                                  //| List(6, 5)
                                                  //| List(10, 4)
                                                  //| List(12, 9)
                                                  //| List(2)

最安全,最简单的方法是将其转换为包含唯一元素的设置

scala> val myList = List(1,2,3,3,3,3,1,1,1,1,4,4,4,5,5,5,6,7,7,7,8) 
myList: List[Int] = List(1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5, 6, 7, 7, 7, 8)
scala> scala.util.Random.shuffle(myList.toSet).take(2)
res1: scala.collection.immutable.Set[Int] = Set(5, 1)

这将确保仅采用唯一元素

考虑在洗牌列表上定义迭代器

class RandList[A] (list: List[A]) {
    val idx = scala.util.Random.shuffle(list)
    val it = idx.iterator
    def next() = if (it.hasNext) Some(it.next) else None
    def getPair() = (next(), next())
}

此方法避免删除元素,因此在每个呼叫中更新列表。

然后,

scala> val a = new RandList(List(1,2,3))
a: RandList[Int] = RandList@7eee8f
scala> a.getPair()
res25: (Option[Int], Option[Int]) = (Some(1),Some(3))
scala> a.getPair()
res26: (Option[Int], Option[Int]) = (Some(2),None)

另一方面,要从列表中删除重复项,请考虑myList.distinctmyList.toSet.toList

如果您的列表具有唯一的元素,则无法定义两次相同的元素:

Scala中的类列表

"返回该列表的n个第一个元素,否则将返回整个列表,如果它的元素少于n个元素。"

最新更新