2012-03-23 29 views
1

當遊戲框架提交重複的表單字段,該值被提交爲平移地圖到另一個

Map("name"->List("value0", "value1", "value2"))`. 

我需要把這些轉化爲

Map("name[0]"->"value0", "name[1]"->"value1", "name[2]"->"value2")) 

用於映射到一個案例類。

我的測試類如下:

@RunWith(classOf[JUnitRunner]) 
class TranslateMapSuite extends FunSuite { 

    test("Translate Map "){ 
    val inputMap = Map("name"->List("value0", "value1", "value2")) 
    val outputMap = TranslateMap.translate(inputMap) 
    assert(outputMap == Map("name[0]"->"value0", "name[1]"->"value1", "name[2]"->"value2")) 
} 

我想出了以下的解決方案,工作,但我不是很滿意:

object TranslateMap{ 
     def translate(inputMap:Map[String, List[String]]) = { 
     inputMap.map ({ 
      case (key, listValue) => { 
       var i = -1 
       listValue.map (value=> { 
         i +=1 
         (key +"[" + i+"]", value) 
       }) 
      } 
      }) 
     }.head.toMap 
    } 

任何建議改善將代碼真的很感激。

回答

6

這裏有一個更地道的版本:

def translate(orig: Map[String, List[String]]) = 
    orig.flatMap { 
    case (k, vs) => vs.zipWithIndex.map { 
     case (v, i) => "%s[%d]".format(k, i) -> v 
    } 
    } 

你可以寫一個稍微更簡潔(但當量)版採用了for -comprehension:

def translate(orig: Map[String, List[String]]) = for { 
    (k, vs) <- orig 
    (v, i) <- vs.zipWithIndex 
} yield "%s[%d]".format(k, i) -> v 
+0

你不應該需要'toMap' – 2012-03-23 14:51:42

+0

啊!好點子。現在編輯。 – 2012-03-23 14:53:33

+0

感謝@TravisBrown,zipWithIndex是我一直在尋找的。 – 2012-03-23 15:17:20