我正在尝试编写一个通用的fill
方法,以下是我到目前为止所提出的方法:
scala> import collection.generic.{GenericTraversableTemplate => GTT}
import collection.generic.{GenericTraversableTemplate=>GTT}
scala> import collection.generic.{TraversableFactory => TF}
import collection.generic.{TraversableFactory=>TF}
scala> def fill[A, CC[X] <: Traversable[X] with GTT[X, CC]]
| (n: Int)(elem: => A)(tf: TF[CC]) = tf.fill(n)(elem)
fill: [A, CC[X] <: Traversable[X] with scala.collection.generic.GenericTraversab
leTemplate[X,CC]](n: Int)(elem: => A)(tf: scala.collection.generic.TraversableFa
ctory[CC])CC[A]
scala> fill(3)('d')(List)
res42: List[Char] = List(d, d, d)
这适用于除数组之外的所有可遍历集合。如何使此代码与数组一起使用?
答案 0 :(得分:10)
如果你不介意创建一个额外的对象,那就是
def fill[CC[_]](n: Int) = new {
def apply[A](elem: => A)(implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
val b = cbf()
1 to n foreach { _ => b += elem }
b.result
}
}
它没有绕过异议(2),但用法很好:
scala> fill[List](3)("wish")
res0: List[java.lang.String] = List(wish, wish, wish)
scala> fill[Array](3)("wish")
res1: Array[java.lang.String] = Array(wish, wish, wish)
答案 1 :(得分:1)
可以稍微改变Rex'解决方案的语法:
class Filler(n: Int) {
def timesOf[A](elem: => A) = new Builder[A](elem)
class Builder[A](elem: => A) {
import scala.collection.generic.CanBuildFrom
def fillIn[CC[_]](implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
val b = cbf()
for (_ <- 1 to n) b += elem
b.result
}
}
}
implicit def int2Filler(n: Int) = new Filler(n)
// use as
(3 timesOf true).fillIn[List]
因为操作符号仅允许用于括号,所以我们不能省略括号。
答案 2 :(得分:0)
我使用Builder
的{{1}}方法在这里改进了Rex的解决方案。使用任何集合,对其执行任何要执行的操作,然后最终将其添加到构建器对象,然后获取其结果。
++=