Reputation: 2802
I must be doing something wrong. I come form a Java background so this stuff should be easy.
I'm wanting to create a mapping between a key and multiple values held in a list:
var keys = Map[String, ListBuffer[String]]()
However, I can't seem to add a value to the list!!! What am I doing wrong??
def put(key: String, value: String) = {
var valueOption = keys.get(key)
var values = valueOption.getOrElse(ListBuffer)
values += value
// value not added
}
I do not want to use a MultiMap because I need to do some other operations which are not easy to do with a MultiMap.
Please help.
Thanks
Upvotes: 3
Views: 633
Reputation: 16399
The other answers are right about how you're not putting the new ListBuffer
back in the Map
, but their example code is verbose. A mutable Map
has getOrElse
and getOrElseUpdate
methods for this. Also, use val
not var
for locals and the keys
member, unless you have reason not to. I sometimes prefer append
to +=
.
def put(key: String, value: String) = {
keys.getOrElseUpdate(key, ListBuffer()) += value
}
Upvotes: 7
Reputation: 9705
The problem is here:
var valueOption = keys.get(key)
var values = valueOption.getOrElse(ListBuffer)
For any nonexistent key, keys.get
will return a None
Option
. You then call getOrElse
, and since the "else" part is used (because it's a None
), a new ListBuffer
is initialized. However, this is all that happens.
In particular, the new ListBuffer
is NOT automatically put into the map. Such an operation wouldn't make sense - getOrElse
is part of the Option
API, it cannot "know" about any collection the Option
is generated from.
To correct your problem, you have to put the new ListBuffer
into the map yourself. An example if you're using a mutable Map:
def put(key: String, value: String) = {
var valueOption = keys.get(key)
var values = valueOption.getOrElse {val b = ListBuffer.empty[String]; keys.put(key,b); b;}
values += value
}
Upvotes: 4
Reputation: 10081
getOrElse
will return the default ListBuffer, which is an empty ListBuffer, if key doesn't exist. You will need to associate this with you key.
Upvotes: 0
Reputation: 5426
the problem is, that by calling getOrElse(ListBuffer)
you do not insert the new ListBuffer into the Map. So you need to add an additional step:
def put(key: String, value: String) = {
var valueOption =
var values = keys.get(key) match {
case None => // key not yet defined
buffer = ListBuffer()
// insert into map!
keys += key -> buffer
buffer
case Some(buffer) => buffer // key is already defined just return it
}
values += value
}
Note that for keys += key -> buffer
to work, i assume, that you use an mutable Map (import from scala.collection.mutable.Map) instad of the default immutable Map
Upvotes: 0