我正在使用以下代码随机选择两个元素:
scala.util.Random.shuffle(myList).take(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.distinct
或myList.toSet.toList
。
如果您的列表具有唯一的元素,则无法定义两次相同的元素:
Scala中的类列表
"返回该列表的n个第一个元素,否则将返回整个列表,如果它的元素少于n个元素。"