マップ内の既存の値を更新するエレガントな方法はありますか?
これは怖すぎるように見えます:
val a = map.get ( something )
if ( a != null ) // case .. excuse my old language
a.apply( updateFunction )
else
map.put ( something, default )
マップ内の既存の値を更新するエレガントな方法はありますか?
これは怖すぎるように見えます:
val a = map.get ( something )
if ( a != null ) // case .. excuse my old language
a.apply( updateFunction )
else
map.put ( something, default )
ほとんどの場合、作成時に更新できるものを挿入できます(たとえば、カウントの場合は、1を入力するだけでなく、0を入力してから1に更新します)。その場合、
map.getOrElseUpdate(something, default).apply(updateFunction)
このように整理できないというまれなケースでは、
map(something) = map.get(something).map(updateFunction).getOrElse(default)
(ただし、something
2回参照する必要があります)。
これは私が通常書いているものです...より良い解決策があるかどうかはわかりません。
map.get(key) match {
case None => map.put(key, defaultValue)
case Some(v) => map(key) = updatedValue
}
実際update
、 とput
は変更可能なマップと同じですが、読みやすくするために、通常はupdate
既存のエントリとput
新しいエントリに使用します。
もう1つのことは、キーの存在を確認せずに最終的な値が何であるかを把握できる場合はmap(key) = value
、 , at と書くだけで、エントリが自動的に作成/置換されることです。
最後に、ステートメント likemap(key) += 1
は実際に機能しMap
(これは通常、関数を含むコレクションに当てはまりupdate
ます)、多くの単純な数値演算も同様です。\
二重プットを解決するには、不変値の代わりに可変オブジェクトを使用します。
class ValueStore(var value: ValueType)
val map = new Map[KeyType, ValueStore]
...
map.get(key) match {
case None => map.put(key, new ValueStore(defaultValue))
case Some(v) => v.value = updatedValue
}
コメントで述べたように、の基礎となる構造は でHashMap
ありHashTable
、実際にはこの変更可能なラッパー クラス アプローチを使用します。HashMap
はより優れたラップアップ クラスですが、重複した計算を行う必要がある場合もあります。
私は愚かです、あなたは(まったく)正しいです:
map.get(key) match {
case None => map.put(key, defaultValue)
case Some(v) => v.apply(updateFunction) // changes state of value
}
ありがとう