Question

J'ai une collection que je veux cartographier dans une nouvelle collection, mais chaque valeur résultante dépend de la valeur avant elle, je pourrais résoudre ceci avec un pli vers

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

Le problème ici est que je dois parcourir toute la liste pour récupérer la liste résultante. Disons que je voulais une fonction qui mappe traverser [a] se déplacer [b] et évaluer uniquement les membres comme je les appelle? Cela me semble être un problème assez conventionnel, alors je me demande s'il y a une approche commune à cela. Ce que j'ai actuellement, c'est:

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

En ce qui concerne la pureté fonctionnelle, vous ne pouvez pas l'exécuter en parallèle, mais sinon cela semble solide.

Un exemple serait; Renvoyez-moi chaque élément et si c'est la première fois que cet élément apparaît auparavant.

val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
 (s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
Était-ce utile?

La solution

Vous pourriez être en mesure d'utiliser la monade de l'État. Voici votre exemple réécrit à l'aide de scalaz:

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)

Autres conseils

On dirait que vous avez besoin Seqview. Utilisation view ou view(from: Int, until: Int) Méthodes pour créer une vue non stricte de la liste.

Je ne comprends vraiment pas votre exemple car votre chèque contient toujours false.

foldLeft est différent. Il en résultera une seule valeur en agrégeant tous les éléments de la liste. Vous avez clairement besoin map (List => List).

Quoi qu'il en soit, répondant à votre question sur la paresse: vous devriez utiliser Stream à la place de List. Stream n'évalue pas la queue avant de l'appeler.

API Stream

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top