3

我不知道如何使以下代码不可变:

def function123(str: String, mapVal: Map[String, String]) = {
    var str1 = str
    mapVal.keySet.foreach({x => 
       str1 = str1.replaceAll(/*some pattern involving x*/, mapVal.get(x).get)})
    str1
}

我可以怀疑我会使用foldLeft参数累加器或嵌套方法,但这只是我的想法。

那么我该怎么做呢?

4

1 回答 1

5

向左折叠

你在这里有一个循环。

具有副作用的循环的不可变版本将foldLeft所有副作用替换为下一个状态创建:

val result = mapVal.foldLeft(str){case (state, (key, value)) => 
  state.replaceAll(/*some pattern involving key*/, value)
}

要在不可变的环境中工作,循环的每次迭代都应该返回值并将前一次迭代的结果作为参数。这正是事实foldLeft

递归

另一种解决方案是递归方法。您应该将循环迭代提取到方法并让该方法最终调用下一次迭代:

def function123(str: String, mapVal: Map[String, String]) = {
  @tailrec def loop(state: String, pairs: List[(String, String)]): String = pairs match {
    case Nil => state
    case (key, value) :: tail =>
      val nextState = state.replaceAll(/*some pattern involving key*/, value)
      loop(nextState, tail)
  }
  loop(str, mapVal.toList)
}

可变循环 -> 不可变

要使具有可变循环的代码不可变,您应该将循环中隐式涉及的所有值提取到某种状态(foldLeft递归方法的单个状态对象或一组参数),然后根据前面的每次迭代结束。

于 2013-06-26T05:48:43.457 回答