4

foreachWithIndexメソッドをScalaコレクションに追加するにはどうすればよいですか?メソッドを使用して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 
    } 
    } 
} 

は、これは動作しません:

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) 

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

答えて

8

あなたは反復処理可能を拡張する必要があります。

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) 

は、より多くの情報のためthis post by Rex Kerrを参照してください。あなたが興味を持っていることのみインデックスに反復されている場合は

4

短い答えは、そのようにすればCCをパラメータ化しなければならないか、またはタイプ推論器がAが何であるか把握できないということです。もう一つの短い答えは、私がthis questionへの答えに記述する方法です。

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

+0

ような何かを行う可能性があります実際にはただ一つの方法だ余分なメソッドのセットからI実装しようとしています。これらの他のメソッドの中には、同じ型の新しいコレクションを作成する必要があるものがあります。 – missingfaktor

2

、あなたにもちょうど全体の売春部分をスキップして

coll.zipWithIndex.foreach { case (elem, index) => 
    /* ... */ 
} 
+0

https://twitter.com/#!/missingfaktor/status/95597737680183297 :-) – missingfaktor

+0

'mapWithIndex'はどうでしょうか?リストは続く。 –