2016-10-20 8 views
1

のStringのためのIntマッピングを生成します。私は出力にリスト内の文字列値に対応するのInt値しようとしています。このコードは使用してリスト

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 

を私は1,2,2,1を期待していたときに出力され、それぞれのIntはシーケンシャルですList内の要素にどのようにマップされるかが一意です。 Listが含まれている場合( "a"、 "b"、 "b"、 "a"、 "r")、1,2,2,1,3を生成する必要があります。 私はこれが不可解な解決策であると理解していますが、私は、機能的に変換する前に、不可解な解決策を試してみようとしています。

リスト内の値にマップされる順次Int値の一意のリストを生成する方法はありますか?

答えて

2
scala> val chars = List("a" , "b" , "b" , "a" , "r") 
chars: List[String] = List(a, b, b, a, r) 

charsの各文字の数値を検索するために使用される個別の文字のうち、Map[String, Int]してください。

scala> val map = chars.distinct.zipWithIndex.toMap 
map: scala.collection.immutable.Map[String,Int] = Map(a -> 0, b -> 1, r -> 2) 

ここで、リストを調べて、各文字の数値を取得します。

scala> chars.flatMap(c => map.get(c) + 1) 
res1: List[Int] = List(1, 2, 2, 1, 3) 

私は、命令的なアプローチが理にかなっていると思います。

+0

ありがとうございますが、タイプミスマッチです。 [エラー] found:Int(1) [エラー]必須:文字列 [エラー] val出力= l.flatMap(c => map.get(c)+ 1) 代わりに:chars.map (c => map.get(c).get + 1) –

1

カウンターは間違った場所で増分されます。これで修正されます:

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 
     } 
    } 
関連する問題