sam
sam

Reputation: 1436

Scala: Iterate over mutable map of maps

I have defined a mutable map of maps

import scala.collection.mutable.Map

val default = Map.empty[String, Int].withDefaultValue(0)
val count = Map.empty[Any, Map[String, Int]].withDefaultValue(default)

which I populate/update as in

count("furniture")("table") += 1
count("furniture")("chair") = 6
count("appliance")("dishwasher") = 1

How can I iterate over all items in count? And why does count.keys return an empty Set()?

Upvotes: 1

Views: 255

Answers (2)

mavarazy
mavarazy

Reputation: 7735

With default, does not create new Map when no value exists in collection, it just returns default value on such requests, and other changes are done on this default value.

count("furniture")("table") += 1
count("furniture")("chair") = 6
count("appliance")("dishwasher") = 1

count("banana") // will return Map with "table", "chair" & "dishwasher"

is equivalent

default("table") += 1
default("chair") = 6
default("dishwasher") = 1

And since you return this default value on any key, this default map will be returned on every call.

Your code will work like this.

count("furniture") = Map.empty[String, Int].withDefaultValue(0)
count("appliance") = Map.empty[String, Int].withDefaultValue(0)

count("furniture")("table") += 1
count("furniture")("chair") = 6
count("appliance")("dishwasher") = 1

Upvotes: 1

Martin Ring
Martin Ring

Reputation: 5426

There are several problems with your approach:

Issue #1:

val default = Map.empty[String,Int].withDefaultValue(0)

defines a value default. There is only one instance of this value and it can not be changed, since you defined as a val.

That means that your count map has a default value which is always the same instance of an empty map. Since count is empty, count("furniture") or count("appliance") is exactly the same as just default.

Issue #2:

withDefaultValue does not add entries to a map it just returns a default for undefined keys.

See @mavarazys answer

Upvotes: 0

Related Questions