将地图翻译成另一个地图

时间:2012-03-23 14:27:21

标签: scala playframework

在Play框架中提交重复的表单字段时,值将以

的形式提交
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
    } 

有关改进代码的任何建议都会非常感激。

1 个答案:

答案 0 :(得分: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编写一个稍微简洁(但等效)的版本 - 理解:

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