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です。

再帰

もう1つの解決策は再帰的な方法です。ループの反復をメソッドに抽出し、このメソッドが最後に次の反復を呼び出すようにする必要があります。

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 に答える