Sie können es nicht wirklich als Einzeiler machen, also sollten Sie sicher sein, dass Sie es brauchen, bevor Sie etwas Komplizierteres schreiben (geschrieben von einem etwas performanceorientierten Blick, da Sie nach "effizient" gefragt haben): Hier ist ein Beispiel davon in Aktion
final case class Var[A](var value: A) { }
def multifold[A,B,C](xs: Traversable[A])(f: A => B)(zero: C)(g: (C,A) => C) = {
import scala.collection.JavaConverters._
val m = new java.util.HashMap[B, Var[C]]
xs.foreach{ x =>
val v = {
val fx = f(x)
val op = m.get(fx)
if (op != null) op
else { val nv = Var(zero); m.put(fx, nv); nv }
}
v.value = g(v.value, x)
}
m.asScala.mapValues(_.value)
}
(auf Ihrem Anwendungsfall Je Sie in eine unveränderliche Karte statt im letzten Schritt packen möchten.):
scala> multifold(List("salmon","herring","haddock"))(_(0))(0)(_ + _.length)
res1: scala.collection.mutable.HashMap[Char,Int] = Map(h -> 14, s -> 6)
Jetzt könnten Sie etwas bemerken komisch hier: Ich benutze eine Java HashMap. Dies liegt daran, dass die HashMaps von Java 2-3x schneller sind als die von Scala. (Sie können das Äquivalent mit einer Scala HashMap schreiben, aber es macht die Dinge nicht schneller als Ihr Original.) Folglich ist dieser Vorgang 2-3x schneller als was Sie gepostet haben. Aber solange du nicht unter schwerem Erinnerungsdruck stehst, tut dir die Erstellung der flüchtigen Sammlungen nicht wirklich weh.
@sschaef Können Sie den Grund für die Änderung "Was ist der beste Weg" zu "Ist es möglich und wenn ja wie?" Erklären? Es muss möglich sein (Turing completness) und es ist leicht einen klugen Weg zu finden. Ich mache auch die Frage unggrammatical –
"Was ist der beste Weg" ist schlechtes Format für eine Frage, normalerweise kann es nicht definitiv beantwortet werden. Aber ich stimme dem Rollback zu, nachdem ich über den Schnitt nachgedacht habe, es hat die Frage nicht besser gemacht. – sschaef