编写通用的“填充”;方法

发布于 2024-12-03 04:52:29 字数 760 浏览 0 评论 0原文

我正在尝试编写一个通用的 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)

这适用于除数组之外的所有可遍历集合。如何使此代码与数组一起使用?

I am trying to write a generic fill method, and following is what I have come up with so far:

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)

This works with all traversable collections except arrays. How do I make this code work with arrays?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

箹锭⒈辈孓 2024-12-10 04:52:29

如果您不介意创建一个额外的对象,那么

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)

If you don't mind creating an extra object, there's

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
  }
}

It doesn't get around objection (2), but the usage is nice:

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)
南冥有猫 2024-12-10 04:52:29

可以稍微改变一下 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]

因为运算符符号只允许用于括号,所以我们不能省略括号。

It is possible to change the syntax of Rex' solution a little bit:

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]

Because operator notation is only allowed for parentheses, we can't omit the brackets.

云胡 2024-12-10 04:52:29

我通过使用 Builder 的 ++= 方法改进了 Rex 的解决方案。使用任何集合,对其执行您想要执行的任何操作,然后最终将其添加到构建器对象中,然后获取其结果。

scala> def fill[CC[_]](n: Int) = new {
     |   def apply[A](elem: => A)
     |               (implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
     |     val b = cbf.apply
     |     b ++= Vector.fill(n)(elem)
     |     b.result
     |   }
     | }
fill: [CC[_]](n: Int)java.lang.Object{def apply[A](elem: => A)(implicit cbf: sca
la.collection.generic.CanBuildFrom[Nothing,A,CC[A]]): CC[A]}

scala> fill[List](3)("hullo")
res8: List[java.lang.String] = List(hullo, hullo, hullo)

I have bettered Rex's solution here by using Builder's ++= method. Use any collection, perform on it whatever operations you want to perform, and then finally add it to the builder object and then take its result.

scala> def fill[CC[_]](n: Int) = new {
     |   def apply[A](elem: => A)
     |               (implicit cbf: CanBuildFrom[Nothing, A, CC[A]]) = {
     |     val b = cbf.apply
     |     b ++= Vector.fill(n)(elem)
     |     b.result
     |   }
     | }
fill: [CC[_]](n: Int)java.lang.Object{def apply[A](elem: => A)(implicit cbf: sca
la.collection.generic.CanBuildFrom[Nothing,A,CC[A]]): CC[A]}

scala> fill[List](3)("hullo")
res8: List[java.lang.String] = List(hullo, hullo, hullo)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文