17

immutable.Map インスタンスの getOrElseUpdate の慣用的な方法は何ですか? 以下のスニペットを使用しますが、冗長で非効率的です

var map = Map[Key, Value]()

def foo(key: Key) = {
  val value = map.getOrElse(key, new Value)
  map += key -> value
  value
}
4

4 に答える 4

15

私はおそらく次のgetOrElseUpdatedような方法を実装します:

def getOrElseUpdated[K, V](m: Map[K, V], key: K, op: => V): (Map[K, V], V) =
  m.get(key) match {
    case Some(value) => (m, value)
    case None => val newval = op; (m.updated(key, newval), newval)
  }

mのマッピングがある場合は元のマップを返すか、マッピングが追加されkeyた別のマップを返します。key -> opこのメソッドの定義は of に似てgetOrElseUpdatemutable.Mapます。

于 2011-04-30T06:48:19.623 に答える
9

あなたの問題を要約しましょう:

  • 不変データ構造のメソッドを呼び出したい
  • 何らかの値を返して、var
  • データ構造は不変であるため、次のことを行う必要があります。
    • 新しい不変データ構造を返す、または
    • 提供されたクロージャーを使用して、メソッド内で割り当てを行います

したがって、署名は次のようにする必要があります

def getOrElseUpdate(key: K): Tuple2[V, Map[K,V]]
//... use it like
val (v, m2) = getOrElseUpdate(k)
map = m2

また

def getOrElseUpdate(key: K, setter: (Map[K,V]) => Unit): V
//... use it like
val v = getOrElseUpdate(k, map = _)

これらのソリューションのいずれかを使用できる場合は、暗黙的な変換を使用して独自のバージョンを追加できますが、署名だけで判断すると、これらのいずれも標準ライブラリにないと思います。

于 2010-12-08T15:20:58.023 に答える
8

そのような方法はありません-マップの値を取得するときのマップの突然変異(更新)は副作用です(これはプログラミングの不変性/関数型スタイルと矛盾します)。

デフォルト値で新しい不変マップを作成する場合、指定されたキーの別の値が存在しない場合は、次の操作を実行できます。

map + (key -> map.getOrElse(key, new Value)) 
于 2010-12-08T10:02:51.030 に答える
2

使用しないのはなぜですか、withDefaultまたはwithDefaultValue不変のマップがある場合は?

于 2010-12-08T14:10:20.160 に答える