Anjan Pathak
Anjan Pathak

Reputation: 11

translating a Map to another

When submitting a repeated form field in play framework, the values are submitted as

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

I need to convert these to

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

for mapping to a case class.

My test class is below:

@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"))
 }

I have come up with the following solution that works but I am not very happy with it:

    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
    } 

Any suggestions on improving the code will be really appreciated.

Upvotes: 1

Views: 169

Answers (1)

Travis Brown
Travis Brown

Reputation: 139038

Here's a more idiomatic version:

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

You can write a slightly more concise (but equivalent) version with a for-comprehension:

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

Upvotes: 6

Related Questions