How to get rid of var using scanLeft


#1

Hi.

How do I get rid of the var isPrevSet ?

case class Po(c: String, on: Option[Boolean])
val start = Po("a", Some(true))
val fisk = List(
	Po("b", Some(true))
	, Po("c", None)
	, Po("d", Some(true))
	, Po("e", None)
	, Po("f", None)
	, Po("g", None)
	, Po("h", None)
	, Po("i", None)
)
var isPrevSet = true
val nipp = fisk.scanLeft(start) { case (prev, cur) =>
	val ret = Po(cur.c, Some(isPrevSet))
	isPrevSet = isPrevSet && cur.on.contains(true)
	ret
}
println(s"${nipp.mkString("\n")}")

What I’m trying to do is to replace each element in fisk of Po’s on with Some(true) iff the previous’ also was Some(true)
The output should be:

Po(a,Some(true))
Po(b,Some(true))
Po(c,Some(true))
Po(d,Some(false))
Po(e,Some(false))
Po(f,Some(false))
Po(g,Some(false))
Po(h,Some(false))
Po(i,Some(false))

Thanks.


#2

Hi,

if i understand correctly, you can thread all required additional values
through scanLeft as well, for example:

val nipp2 = fisk.scanLeft((start, true)) { case ((prev, prevSet), cur) =>
  val ret = Po(cur.c, Some(prevSet))
  (ret, prevSet && cur.on.contains(true))
}

This simple example has the cost of adding another value to each element
in the list. This can be improved by creating a better type than a tuple
(maybe Acc(list: List[Po], prevSet: Boolean) so you only have one
additional property as in the var case. The basic concept is, that
everything you need inside the scanLeft has to “come in” as argument
somehow.

Not sure if I understood correctly, hope it helps…

-Eike

Andreas Joseph Krogh noreply@users.scala-lang.org writes:


#3

Perfect! You got me on the right track, thanks.