1

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 ?

2 Answers 2

2
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.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks but I receive error : , type mismatch; [error] found : Int(1) [error] required: String [error] val output = l.flatMap(c => map.get(c) + 1) , I instead used : chars.map(c => map.get(c).get + 1)
1

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
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.