我无法弄清楚如何使以下代码成为不可变的:
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
或带参数累加器的嵌套方法,但这些只是我的想法。
那我该怎么做?
答案 0 :(得分:5)
<强> foldLeft 强>
你这里有一个循环。
带有副作用的循环的不可变版本是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)
}
可变循环 - &gt;不可变强>
要使具有可变循环的代码成为不可变的,你应该将循环中变化中隐含的所有值提取到某种状态(foldLeft
的单个状态对象或递归方法的一组参数)然后生成基于每次迭代结束时的前一个新状态。