Eve Freeman
Eve Freeman

Reputation: 33155

Scala var/val local variable best practice

I need to accumulate results within a Map. I've tried doing this with .map, .reduceLeft, and .foldLeft(init(m)), before realizing I wasn't using them properly. The expression call needs the latest map in order to get the right answer.

I've ended up with this, which works, but I feel a bit dirty for having a var Map that gets updated in the loop. Is this acceptable from a Scala best practice perspective? Are there any good ways to rewrite it more idiomatically?

val acc = "some key name"
val id = "some other key name"
val myColl = List(1, 2, 3, 4, 5)

// oversimplification (these things actually do work and access other keys in the map)
def expression(m:Map[String, Int]) = (m(acc)) + (m(id))
def init(m:Map[String, Any]) = 0

// can this be made better?
def compute(m: Map[String, Int]) = {
  var initMap = m + (acc -> init(m))
  for(k <- myColl) {
    initMap = initMap + (id -> k)
    val exp = expression(initMap)
    initMap = initMap + (acc -> exp)
  }
  initMap(acc)
}

compute(Map())

Upvotes: 2

Views: 604

Answers (1)

jcern
jcern

Reputation: 7848

I am not sure this is much cleaner, but it will avoid the use of the var:

def compute(m:Map[String, Int]) = {
  val initMap = myColl.foldLeft(m + (acc -> init(m)))( (e, k) => 
    e + (id -> k) + (acc -> expression(e + (id -> k))))
  initMap(acc)
}

Should return the same result

Upvotes: 2

Related Questions