I have a map of Int->Queue, and I'm adding to the queues one entry at a time. At the end of the process I need to iterate over the keys and values (because I want to convert the Queues to Arrays), but scala says there are no keys/values in the map. Some simplified code below for illustration purposes. What is going on here? The result of m(4) below is also puzzling.
import scala.collection.mutable.Queue
val m = Map[Int, Queue[Int]]().withDefaultValue(Queue[Int]())
m(1) += 10
res25: scala.collection.mutable.Queue[Int] = Queue(10)
m(1) += 10
res26: scala.collection.mutable.Queue[Int] = Queue(10, 10)
m(1)
res35: scala.collection.mutable.Queue[Int] = Queue(10, 10)
m(4)
res37: scala.collection.mutable.Queue[Int] = Queue(10, 10)
m.keys
res28: Iterable[Int] = Set()
m
res36: scala.collection.immutable.Map[Int,scala.collection.mutable.Queue[Int]] = Map()
Using scala 2.10.3.
You never add anything to the map. You are getting the mutable queue that you set as the default value and modifying that.
Yes, you do have to check if the Queue
at a given index has been created or not, but the syntax need not be quite so "laborious."
import scala.collection.mutable.Queue
val mutablemap = scala.collection.mutable.Map[Int, Queue[Int]]()
mutablemap(9) = mutablemap.lift(9).fold(Queue(99))(_ += 99)
mutablemap(2) = mutablemap.lift(2).fold(Queue(22))(_ += 22)
mutablemap(9) = mutablemap.lift(9).fold(Queue(19))(_ += 19)
mutablemap(2) = mutablemap.lift(2).fold(Queue(12))(_ += 12)
mutablemap(9) // res0: scala.collection.mutable.Queue[Int] = Queue(99, 19)
mutablemap(2) // res1: scala.collection.mutable.Queue[Int] = Queue(22, 12)
update
On further reflection, your original design wasn't too far off the mark.
import scala.collection.mutable.Queue
val mutablemap =
scala.collection.mutable.Map[Int, Queue[Int]]().withDefault(_ => Queue[Int]())
mutablemap(3) = mutablemap(3) += 37
mutablemap(3) = mutablemap(3) += 45
mutablemap(6) = mutablemap(6) += 60
mutablemap(6) = mutablemap(6) += 62
mutablemap(3) // res0: scala.collection.mutable.Queue[Int] = Queue(37, 45)
mutablemap(6) // res1: scala.collection.mutable.Queue[Int] = Queue(60, 62)
Leveraging puhlen's answer:
First, I need to switch to a mutable map. Second, the use of withDefaultValue seems to be irrelevant to this problem (which is counterintuitive).
val mutablemap = scala.collection.mutable.Map[Int, Queue[Int]]()
When adding key-value pairs to the map, I have to laboriously check to see if the key exists first (because I don't want to destroy any pre-existing key-value pair, because I'm incrementally building up the queues):
if (mutablemap.contains(key)) {
// mutate the existing Queue
mutablemap(key) += new_value
} else {
// key was not in map; start a new Queue
mutablemap += key -> Queue[Int](first_value)
}