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

时间:2014-01-31 17:05:38

标签: scala

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

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

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

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

5 个答案:

答案 0 :(得分:0)

更多的背景会很好;就像在,你为什么不把你的列表转换成更容易处理这个任务的东西,比如迭代器或数组?

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

  1. 使用列表的长度从索引数组中选取两个随机数,检查两个随机数是否相同,然后从列表中提取这些数字。
  2. 取1,取出,然后取另一个而不是一次取两个。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

一次洗牌就足够了。但是,如果您需要非重复项,则列表中的列表不得包含重复项。

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)

答案 3 :(得分:0)

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

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)

这将确保只采用唯一的元素

答案 4 :(得分:-1)

如果您的列表具有唯一元素,则根据定义不可能将相同的元素两次使用:

class List in scala

“返回此列表的n个第一个元素,如果它少于n个元素,则返回整个列表。”