0

我正在处理的 Web 应用程序的一部分处理需要绑定到模型(案例类)实例集合的表单。看到这个问题

因此,如果我要一次添加多个用户,表单字段将命名为email[0]email[1]password[0]password[1]等。

发布表单会导致Map[String, Seq[String]]

现在,我想做的是按索引分批处理 Map,这样每次迭代我都可以绑定一个 User 实例,创建一个List[User]作为绑定的最终结果。

我正在考虑的黑客方法是在 Map 键中进行正则表达式匹配"[\d]",然后通过过滤器或计数找到最高索引;有了它,然后(0..n).toList map{ ?? }通过表单字段行的数量,相应地调用绑定/验证方法(也需要 a Map[String, Seq[String]])。

实现这一目标的简洁方法是什么?

4

1 回答 1

1

假如说:

  1. 所有地图键都在形式"field[index]"
  2. 每个键只有一个值Seq
  3. 如果有条目,"email[x]"则有条目,"password[x]"反之亦然。

我会做这样的事情:

val request = Map(
  "email[0]" -> Seq("alice@example.com"),
  "email[1]" -> Seq("bob@example.com"),
  "password[0]" -> Seq("%vT*n7#4"),
  "password[1]" -> Seq("Bfts7B&^")
)

case class User(email: String, password: String)

val Field = """(.+)\[(\d+)\]""".r

val userList = request.groupBy { case (Field(_, idx), _) => idx.toInt }
                      .mapValues { userMap =>
                          def extractField(name: String) =
                              userMap.collect{case (Field(`name`, _), values) => values.head}.head
                          User(extractField("email"), extractField("password"))}    
                      .toList.sortBy(_._1).map(_._2)

// Exiting paste mode, now interpreting.

request: scala.collection.immutable.Map[String,Seq[String]] = Map(email[0] -> List(alice@example.com), 
email[1] -> List(bob@example.com), password[0] -> List(%vT*n7#4), password[1] -> List(Bfts7B&^))
defined class User
Field: scala.util.matching.Regex = (.+)\[(\d+)\]
userList: List[User] = List(User(alice@example.com,%vT*n7#4), User(bob@example.com,Bfts7B&^))
于 2012-10-01T13:37:28.047 回答