在 Scala 中打乱一些列表序列
Shuffle some sequence of List in Scala
我正在使用 scala.util.Random
,然后我知道如何随机排列列表。随机化数组列表中的顺序非常有用,例如:
val List(a, b, c, d) = Random.shuffle(List(1,2,3,4))
it will result
a = 1
b = 3
c = 2
d = 4
a,b,c,d的结果可以是1到4之间的任意随机值。
但问题是我们不能这样做:
val a:List = List(1,2,Random.shuffle(3,4,5))
如果你们对这个案例有任何线索,请分享。如果不是,请说明原因。
谢谢!
val a:List = List(1,2,Random.shuffle(3,4,5))
这行会给出类型错误
原因
Shuffle 不接受 var 参数,List apply 方法也不同时接受元素和 List 作为参数。这就是在标准库中声明 shuffle 的方式。
def shuffle[T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: CanBuildFrom[CC[T], T, CC[T]]): CC[T] = {
val buf = new ArrayBuffer[T] ++= xs
def swap(i1: Int, i2: Int) {
val tmp = buf(i1)
buf(i1) = buf(i2)
buf(i2) = tmp
}
for (n <- buf.length to 2 by -1) {
val k = nextInt(n)
swap(n - 1, k)
}
(bf(xs) ++= buf).result()
}
改为这样做
val a = List(1, 2) ++ Random.shuffle(List(3, 4, 5))
如果你想要更友好 API 只需像这样声明一个隐式
implicit class ListUtils[A](list: List[A]) {
import scala.util.Random
def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
}
Scala REPL
scala> import scala.util._
scala> implicit class ListUtils[A](list: List[A]) {
| def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
| }
defined class ListUtils
scala> List(1, 2).addShuffling(3, 4, 5)
res3: List[Int] = List(1, 2, 5, 3, 4)
矢量更适合长列表。对长列表使用矢量实现
implicit class VectorUtils[A](vec: Vector[A]) {
def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
}
Scala REPL
implicit class VectorUtils[A](vec: Vector[A]) {
import scala.util.Random
def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
}
Vector(1, 2).addShuffling(3, 4, 5)
// Exiting paste mode, now interpreting.
defined class VectorUtils
res1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
我正在使用 scala.util.Random
,然后我知道如何随机排列列表。随机化数组列表中的顺序非常有用,例如:
val List(a, b, c, d) = Random.shuffle(List(1,2,3,4))
it will result
a = 1
b = 3
c = 2
d = 4
a,b,c,d的结果可以是1到4之间的任意随机值。 但问题是我们不能这样做:
val a:List = List(1,2,Random.shuffle(3,4,5))
如果你们对这个案例有任何线索,请分享。如果不是,请说明原因。
谢谢!
val a:List = List(1,2,Random.shuffle(3,4,5))
这行会给出类型错误
原因
Shuffle 不接受 var 参数,List apply 方法也不同时接受元素和 List 作为参数。这就是在标准库中声明 shuffle 的方式。
def shuffle[T, CC[X] <: TraversableOnce[X]](xs: CC[T])(implicit bf: CanBuildFrom[CC[T], T, CC[T]]): CC[T] = {
val buf = new ArrayBuffer[T] ++= xs
def swap(i1: Int, i2: Int) {
val tmp = buf(i1)
buf(i1) = buf(i2)
buf(i2) = tmp
}
for (n <- buf.length to 2 by -1) {
val k = nextInt(n)
swap(n - 1, k)
}
(bf(xs) ++= buf).result()
}
改为这样做
val a = List(1, 2) ++ Random.shuffle(List(3, 4, 5))
如果你想要更友好 API 只需像这样声明一个隐式
implicit class ListUtils[A](list: List[A]) {
import scala.util.Random
def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
}
Scala REPL
scala> import scala.util._
scala> implicit class ListUtils[A](list: List[A]) {
| def addShuffling(xs: A*) = list ++ Random.shuffle(xs.toList)
| }
defined class ListUtils
scala> List(1, 2).addShuffling(3, 4, 5)
res3: List[Int] = List(1, 2, 5, 3, 4)
矢量更适合长列表。对长列表使用矢量实现
implicit class VectorUtils[A](vec: Vector[A]) {
def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
}
Scala REPL
implicit class VectorUtils[A](vec: Vector[A]) {
import scala.util.Random
def addShuffling(xs: A*) = vec ++ Random.shuffle(xs.toVector)
}
Vector(1, 2).addShuffling(3, 4, 5)
// Exiting paste mode, now interpreting.
defined class VectorUtils
res1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)