Frage

Wie füge ich a hinzu foreachWithIndex Methode zu Scala -Sammlungen?

Das könnte ich mir bisher einfallen lassen:

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

Das funktioniert nicht:

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

Erhöht den folgenden Fehler:

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

Der Code funktioniert jedoch, wenn ich die Conversion -Methode explizit anwende:

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

Ausgabe:

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

Wie kann ich es ohne explizite Anwendung einer Conversion -Methode damit zum Laufen bringen? Vielen Dank.

War es hilfreich?

Lösung

Sie müssen iterable erweitern:

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

Ausgang:

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

Sehen Dieser Beitrag von Rex Kerr für mehr Informationen.

Andere Tipps

Die kurze Antwort ist, dass Sie parametrisieren müssen CC Wenn Sie es so tun oder der Typ "Inferenzer" kann nicht herausfinden, was A ist. Die andere kurze Antwort ist, wie ich es in der Antwort auf beschreibe diese Frage.

Um ein bisschen mehr zu erweitern, gibt es wirklich keinen Grund, warum Sie brauchen CC <: TraversableLike-Lassen Sie es einfach eine nehmen Traversable und beginnen Sie mit iforeach[A](coll: Traversable[A])! Sie müssen keine ausgefallenen Grenzen verwenden, um eine Superklasse/Superrätin zu verwenden. Wenn Sie etwas komplizierteres tun möchten, wo Sie eine andere Sammlung mit erhaltenen Sammlungstypen zurückgeben, müssen Sie Bauherren und dergleichen verwenden, was ich in der anderen Frage beschreibe.

Wenn das, was Sie interessiert

coll.zipWithIndex.foreach { case (elem, index) =>
  /* ... */
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top