4

foreachWithIndexScalaコレクションにメソッドを追加するにはどうすればよいですか?

これは私がこれまでに思いついたものです:

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

これは機能しません:

Vector(9, 11, 34).foreachWithIndex { (el, i) =>
  println(el, i)
}

次のエラーが発生します。

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

ただし、変換方法を明示的に適用すると、コードは機能します。

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

出力:

(9,0)
(11,1)
(34,2)

変換方法を明示的に適用せずに動作させるにはどうすればよいですか?ありがとう。

4

3 に答える 3

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

出力:

(9,0)
(11,1)
(34,2)

詳細については、RexKerrによるこの投稿を参照してください。

于 2011-07-25T22:56:55.903 に答える
4

CC簡単に言うと、そのようにすると、型推論器が何であるかを理解できない場合は、パラメーター化する必要がありAます。もう1つの簡単な答えは、この質問への回答で説明した方法で行うことです。

もう少し拡張するために、あなたが必要とする理由は本当にありませんCC <: TraversableLike-ただそれを取り、Traversable始めてiforeach[A](coll: Traversable[A])ください!スーパークラス/スーパートレイトを使用するために、派手なタイプの境界を使用する必要はありません。コレクションタイプが保持された別のコレクションを返すような、より複雑なことをしたい場合は、別の質問で説明しているビルダーなどを使用する必要があります。

于 2011-07-25T22:56:18.177 に答える
2

興味のあることがインデックスでの反復のみである場合は、ポン引きの部分全体をスキップして、次のようなことを行うこともできます。

coll.zipWithIndex.foreach { case (elem, index) =>
  /* ... */
}
于 2011-07-25T23:05:38.770 に答える