Reputation: 53896
Using this code I'm attempting to output an Int value that corresponds to string value in List :
val l = List("a" , "b" , "b" , "a");
var counter = 0;
var isAdded = new scala.collection.mutable.ListBuffer[String]();
val map = scala.collection.mutable.HashMap.empty[String,Int]
def getId(m : String) : Int = {
if(map.isDefinedAt(m)){
map.get(m).get
}
else {
map += m -> counter
counter = counter + 1
counter
}
}
(l.map(m => getId(m))).foreach(println)
1
2
1
0
is outputted when I'm expecting 1,2,2,1
, each Int is sequential and unique in how it maps to the element in List. If List contained ("a" , "b" , "b" , "a" , "r") then 1,2,2,1,3
should be generated.
I understand this is an imperative solution attempt but I'm attempting to try an imperative solution before converting to functional.
How to generate a unique List of sequential Int values that map to the values in the List ?
Upvotes: 1
Views: 89
Reputation: 2101
Your counter is incremented at the wrong place. This fixes it:
def getId(m : String) : Int = {
if(map.isDefinedAt(m)){
map.get(m).get
}
else {
counter = counter + 1 // should be incremented before adding to map
map += m -> counter
counter
}
}
Upvotes: 1
Reputation: 20295
scala> val chars = List("a" , "b" , "b" , "a" , "r")
chars: List[String] = List(a, b, b, a, r)
Make a Map[String, Int]
out of the distinct characters that will be used to lookup the numeric value for each character in chars
.
scala> val map = chars.distinct.zipWithIndex.toMap
map: scala.collection.immutable.Map[String,Int] = Map(a -> 0, b -> 1, r -> 2)
Now, go through the list and get the numeric value for each character.
scala> chars.flatMap(c => map.get(c) + 1)
res1: List[Int] = List(1, 2, 2, 1, 3)
I think an imperative approach would be more difficult to reason about.
Upvotes: 2