Anreicherung von Scala -Sammlungen mit einer Methode
-
26-10-2019 - |
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.
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) =>
/* ... */
}