How to update current values ​​in mutable.Map?

Is there an elegant way to update an existing value on a map?

This looks too scary:

val a = map.get ( something ) if ( a != null ) // case .. excuse my old language a.apply( updateFunction ) else map.put ( something, default ) 
+7
source share
3 answers

In most cases, you can embed something that can be updated when it is created (for example, if it is counted, you put 0 in it and then update to 1 instead of just putting 1 at the beginning). In this case

 map.getOrElseUpdate(something, default).apply(updateFunction) 

On rare occasions when you cannot organize like this,

 map(something) = map.get(something).map(updateFunction).getOrElse(default) 

(but you must refer to something twice).

+11
source

This is what I usually write ... not sure if there are better solutions.

 map.get(key) match { case None => map.put(key, defaultValue) case Some(v) => map(key) = updatedValue } 

In fact, update and put same for mutable display, but I usually use update for existing records and put for new, just for readability.

Another thing is that if you can understand what the final value is without checking the existence of the key, you can simply write map(key) = value , while it automatically creates / replaces the record.

Finally, expressions such as map(key) += 1 actually work in Map (this is usually true for collections with the update function), as well as for many simple numerical operations. \


To resolve double-tagging, use a mutable object instead of immutable values:

 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 } 

As I mentioned in a comment, the basic structure of a HashMap is a HashTable , which actually uses this mutable shell class approach. HashMap is a more cool class, but sometimes you need to do duplicate calculations.

+3
source

I'm stupid, you're (quite) right:

 map.get(key) match { case None => map.put(key, defaultValue) case Some(v) => v.apply(updateFunction) // changes state of value } 

TSC thanks

0
source