[英]Scala, a cross between a foldLeft and a map supporting lazy evaluation
我有一個要映射到新集合的集合,但是每個結果值都以某種方式取決於它之前的值。我可以用leftFold解決
val result:List[B] = (myList:List[A]).foldLeft(C -> List.empty[B]){
case ((c, list), a) =>
..some function returning something like..
C -> (B :: list)
}
這里的問題是我需要遍歷整個列表以檢索結果列表。 說我想要一個將TraversableOnce [A]映射到TraversableOnce [B]並僅評估成員的函數? 在我看來,這是一個相當常規的問題,因此我想知道是否存在一種通用的方法。 我目前擁有的是:
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
}
}
}
就功能純度而言,您不能並行運行它,但是聽起來似乎不錯。
一個例子是; 給我返回每個元素,如果這是該元素第一次出現之前。
val elements:TraversableOnce[E]
val result = elements.mappyFoldyFunction(Set.empty[E]) {
(s, e) => (s + e) -> (e -> s.contains(e))
}
result:TraversableOnce[(E,Boolean)]
您可能可以使用State Monad。 這是您使用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)
我真的不理解您的示例,因為您的包含檢查將始終為false
。
foldLeft
是不同的。 通過匯總列表的所有元素,將得到一個單一值。 您顯然需要map
( List
=> List
)。
無論如何,回答關於懶惰的問題:您應該使用Stream
而不是List
。 Stream
在實際調用它之前不會評估它的尾巴。
看起來您需要SeqView 。 使用view
或view(from: Int, until: Int)
方法創建列表的非嚴格視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.