blue-sky
blue-sky

Reputation: 53896

Generate Int mapping for String in List

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

Answers (2)

Samar
Samar

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

Brian
Brian

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

Related Questions