Scala, eine Kreuzung zwischen einem Faltblatt und einer Karte, die eine faule Bewertung unterstützt

StackOverflow https://stackoverflow.com/questions/19841403

Frage

Ich habe eine Sammlung, die ich einer neuen Sammlung zuordnen möchte. Jeder resultierende Wert hängt jedoch in irgendeiner Weise vom Wert ab. Ich könnte dies mit einem linken Mal lösen

val result:List[B] = (myList:List[A]).foldLeft(C -> List.empty[B]){ 
  case ((c, list), a) =>
    ..some function returning something like..
    C -> (B :: list)
} 

Das Problem hier ist, dass ich die gesamte Liste durcharbeiten muss, um die resultierende Liste abzurufen. Sagen Sie, ich wollte eine Funktion, die Karten traversableonce [a] zu traversableonce [b] und nur Mitglieder bewerten, wie ich sie nenne? Es scheint mir ein ziemlich konventionelles Problem zu sein, also frage ich mich, ob es einen gemeinsamen Ansatz gibt. Was ich derzeit habe ist:

implicit class TraversableOnceEx[T](val self : TraversableOnce[T]) extends AnyVal {

   def foldyMappyFunction[A, U](a:A)(func:(A,T) => (A,U)):TraversableOnce[U] = {
     var currentA = a
     self.map { t =>
        val result = func(currentA, t)
        currentA = result._1
        result._2
     }
   } 
}

Was die funktionale Reinheit angeht, konnten Sie sie nicht parallel ausführen, aber ansonsten scheint es so gut zu sein.

Ein Beispiel wäre; Geben Sie mich jedes Element zurück und wenn es das erste Mal ist, dass das Element zuvor erschien.

val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
 (s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
War es hilfreich?

Lösung

Möglicherweise können Sie die staatliche Monade nutzen. Hier ist Ihr Beispiel, das mit Scalaz neu geschrieben wurde:

import scalaz._, Scalaz._

def foldyMappy(i: Int) = State[Set[Int], (Int, Boolean)](s => (s + i, (i, s contains(i))))

val r = List(1, 2, 3, 3, 6).traverseS(foldyMappy)(Set.empty[Int])._2

//List((1,false), (2,false), (3,false), (3,true), (6,false))
println(r)

Andere Tipps

Es sieht so aus, als ob du es brauchst Seqview. Verwenden view oder view(from: Int, until: Int) Methoden zum Erstellen einer nicht strengen Ansicht der Liste.

Ich verstehe Ihr Beispiel wirklich nicht, da Ihre Enthaltungsprüfung immer dazu führen wird false.

foldLeft ist anders. Dies führt zu einem einzigen Wert, indem alle Elemente der Liste zusammengefasst werden. Sie brauchen eindeutig map (List => List).

Beantworten Sie Ihre Frage nach Faulheit: Sie sollten verwenden Stream Anstatt von List. Stream Bewertet den Schwanz nicht, bevor er ihn tatsächlich anruft.

Stream -API

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top