输出Iterable.sliding作为元组

时间:2011-01-17 20:48:20

标签: scala collections

集合上的滑动方法以X[Iterable[A]]的形式返回给定大小的滑动窗口,其中X是集合的类型,A是元素类型。我经常需要两三个元素,我更喜欢将它们命名。 sliding(2)的一个丑陋的解决方法如下:

points.sliding(2).foreach{ twoPoints =>
      val (p1,p2) = (twoPoints.head,twoPoints.last)
      //do something
}

这很糟糕,只适用于两个元素。另请注意

(a,b) = (twoPoints(0),twoPoints(1))

不起作用。

3 个答案:

答案 0 :(得分:17)

上周我在this回答中做了很多。

points.sliding(2).foreach { case X(p1, p2) => ... }

如果pointsArray,则将X替换为Array。如果是List,请将X替换为List,依此类推。

请注意,您正在进行模式匹配,因此您需要{}而不是()作为参数。

答案 1 :(得分:4)

twoPoints似乎是一个列表。试试这个:

points.sliding(3).foreach{ _ match {
  case Seq(a, b, c) => {
      //do something
  }
}

你会感到惊讶的是什么样的kung fo模式匹配可以让你逃脱。

答案 2 :(得分:1)

我最近想在滑动迭代器中加一点糖,所以我想出了这个:

implicit class SlidingOps[A](s: Seq[A]) {
  def slidingPairs = (s, s.tail).zipped
  def slidingTriples = (s, s.tail, s.tail.tail).zipped
}

这适用于任何Seq,但对List最有效。 .zipped返回scala.runtime.Tuple2Zipped(或Tuple3Zipped为3元素元组)对象,它定义了几个熟悉的高阶方法,以便它们的参数采用多个参数,因此您可以编写:< / p>

points.slidingPairs.foreach { (a, b) => ... }

甚至:

(1 to 10).slidingTriples.map(_ + _ + _)

如果您希望它对非列表类型非常有效,则可以进一步优化实现。