使用方法丰富Scala集合

mis*_*tor 4 scala implicit-conversion scala-collections enrich-my-library

如何foreachWithIndex在Scala集合上添加方法?

这是我到目前为止所能提出的:

implicit def iforeach[A, CC <: TraversableLike[A, CC]](coll: CC) = new {
  def foreachWithIndex[B](f: (A, Int) => B): Unit = {
    var i = 0
    for (c <- coll) {
      f(c, i)
      i += 1
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用:

Vector(9, 11, 34).foreachWithIndex { (el, i) =>
  println(el, i)
}
Run Code Online (Sandbox Code Playgroud)

引发以下错误:

error: value foreachWithIndex is not a member of scala.collection.immutable.Vector[Int]
Vector(9, 11, 34).foreachWithIndex { (el, i) =>
Run Code Online (Sandbox Code Playgroud)

但是,当我明确应用转换方法时,代码可以正常工作:

iforeach[Int, Vector[Int]](Vector(9, 11, 34)).foreachWithIndex { (el, i) =>
  println(el, i)
}
Run Code Online (Sandbox Code Playgroud)

输出:

(9,0)
(11,1)
(34,2)
Run Code Online (Sandbox Code Playgroud)

如果没有明确应用转换方法,如何使其工作?谢谢.

kir*_*uku 8

你需要扩展Iterable:

class RichIter[A, C](coll: C)(implicit i2ri: C => Iterable[A]) {
    def foreachWithIndex[B](f: (A, Int) => B): Unit = {
    var i = 0
    for (c <- coll) {
      f(c, i)
      i += 1
    }
  }
}

implicit def iter2RichIter[A, C[A]](ca: C[A])(
    implicit i2ri: C[A] => Iterable[A]
): RichIter[A, C[A]] = new RichIter[A, C[A]](ca)(i2ri)

Vector(9, 11, 34) foreachWithIndex {
  (el, i) => println(el, i)
}
Run Code Online (Sandbox Code Playgroud)

输出:

(9,0)
(11,1)
(34,2)
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Rex Kerr的这篇文章.