My codes looks like this:
type Occurrences = List[(Char, Int)]
def subtract(x: Occurrences, y: Occurrences): Occurrences = for {
(theChar, theInt) <- x
yMap = y.toMap
finalInt = theInt - yMap.getOrElse(theChar,0)
if finalInt != 0
} yield (theChar, finalInt)
I was wondering whether yMap= y.toMap
is evaluated only once or many times.. If it was evaluated many times, what would be the correct syntax to make it to be evaluated only once?
Just bring the ymap = y.toMap
part out of the for
comprehension.
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
val yMap = y.toMap
for {
(theChar, theInt) <- x
finalInt = theInt - yMap.getOrElse(theChar, 0)
if finalInt != 0
} yield (theChar, finalInt)
}
Scala For Comprehensions is just a syntactic sugar.
For instance your code will be translated to the following code by compiler (not exactly the following code but the concept is the same):
def subtract(x: Occurrences, y: Occurrences): Occurrences = x map {
case (theChar, theInt) =>
def yMap = y.toMap
def finalInt = theInt - yMap.getOrElse(theChar, 0)
(theChar, finalInt)
} filter {
case (_, theInt) =>
theInt != 0
}
So any expression inside the map
part will be executed for every item of the collection (x
in this case). By moving the y = y.toMap
part out of the for
block the code will be translated into :
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
def yMap = y.toMap
x map {
case (theChar, theInt) =>
def finalInt = theInt - yMap.getOrElse(theChar, 0)
(theChar, finalInt)
} filter {
case (_, theInt) =>
theInt != 0
}
}
which is most probably what you really want.