How to modify a variable in a foreach loop?

foreach, scala

Solution

`foreach` is actually not the right tool to accomplish what you want. The reason it doesn't work is that a method parameter is not a variable, but an immutable value in scala. You could use a `var`, but that would not be the preferred way in Scala. Instead, you can fold over the replacements and give the original text as the start value:

def censor(text: String, replacements: Map[String, String]): String = {
  replacements.foldLeft(text){ case (text, (key, replacement)) => text.replace(key, replacement)}
}

Or in a shorter version:

def censor(text: String, replacements: Map[String, String]): String = {
  replacements.foldLeft(text)((t, r) => t.replace(r._1, r._2))
}

To explain, in case you're not familiar, `fold` is exactly the functional pattern of iterating of a collection and building or updating an accumulated value as you go. It takes an initial value and a function from the previous value and the current item to the next value, and returns the final value. The `left` and `right` variations simply refer to whether you're folding over your sequence backwards or forwards, which could make a difference in terms of performance and results, depending on your data structure and the nature of the function you pass.

See also: http://www.scala-lang.org/api/2.11.1/index.html#scala.collection.Seq

Problem

I have a `Map` with following sample content: ``` var replacements: Map[String, String] = Map("a" -> "1", "b" -> "2", "c" -> "3") ``` and the following method: ``` def censor(text: String, replacements: Map[String, String]): String = { replacements.keys.foreach(key => text = text.replace(key, replacements(key))) return text } ``` The method should replace all `key`s found in `text` with its value assigned in `replacements`. The problem is the command `text = text.replace(key, replacements(key))` inside the `foreach` loop. So my question is: How to modify the variable `text` inside the `foreach` loop?

Original source