我正在处理的 Web 应用程序的一部分处理需要绑定到模型(案例类)实例集合的表单。看到这个问题
因此,如果我一次添加多个用户,表单字段将被命名为 email[0]
、email[1]
、password[0]
、password[1]
等。
过帐表单会导致Map[String, Seq[String]]
现在,我想做的是按索引批量处理 Map,以便每次迭代我都可以绑定一个 User 实例,创建一个List[User]
作为绑定的最终结果。
我正在考虑的黑客方法是正则表达式匹配 Map 键中的"[d]"
,然后通过过滤器或计数找到最高索引; 有了它,然后(0..n).toList map{ ?? }
表单字段行的数量,相应地调用绑定/验证方法(也需要Map[String, Seq[String]]
)。
实现此目的的简洁方法是什么?
假设:
- 所有地图键均采用表格
"field[index]"
- 每个键
Seq
中只有一个值。 - 如果有
"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&^))