Scala对map进行迭代,并将singleton List变成singleton



我试图在Map中提取List[T]类型的值,使其仅为T。例如:

val c = Map(1->List(1), 2-> List(2), 3->List(3));

会变成

Map(1->1,2->2,3->3);

以下是我迄今为止所写的内容:

val Some(values) = request.body.asFormUrlEncoded.foreach {
  case (key,value) =>
    Map(key->value.head);  
};

这是我收到的错误:

constructor cannot be instantiated to expected type; found : (T1, T2) required: scala.collection.immutable.Map[String,Seq[String]]

编辑:这是关于这一行的:

case (key,value) =>

第2版:request.body.asFormUrl编码示例输出

Some(Map(test -> List(324)))
Some(Map(SpO2 -> List(456), ETCO2 -> List(123)))

您确定列表中总是只有一个元素吗?如果是这样的话,你应该这样做,这是显而易见的,而且如果你意外得到一个坏列表(没有一个元素),它会抛出一个错误。

c.map { case (k, List(v)) => k -> v }
// Map(1 -> 1, 2 -> 2, 3 -> 3)

如果你的列表可以有多个元素,而你只想要第一个,你可以这样做(在空列表上会出错):

val d = Map(1 -> List(1), 2 -> List(2,4,6), 3 -> List(3))
d.map { case (k, List(v, _*)) => k -> v }
// Map(1 -> 1, 2 -> 2, 3 -> 3)

如果您的列表可能没有一个元素,并且希望忽略任何非单例列表而不是抛出错误,请使用collect而不是map:

val e = Map(1 -> List(1), 2 -> List(2,4,6), 3 -> List(3), 4 -> List())
e.collect { case (k, List(v)) => k -> v }
// Map(1 -> 1, 3 -> 3)

至于您的代码:

val Some(values) = request.body.asFormUrlEncoded.foreach {
  case (key,value) =>
    Map(key->value.head);  
};

这真的没有任何意义。

首先,foreach不返回任何内容,因此将其结果分配给变量永远不会起作用。您可能希望它是一个map,以便它返回一个集合。

其次,你使用Some会让人觉得你不理解Option,所以你可能想了解一下。

第三,如果您希望结果是Map(对的集合),那么您只希望返回对key->value.head,而不是Map。

第四,如果您在case (key,value)上得到匹配的错误,那么asFormUrlEncoded可能实际上并没有返回对的集合。你应该看看它的实际类型。

最后,分号是不必要的。你应该移除它们。


根据您的评论编辑

由于request.body.asFormUrlEncoded实际上返回了类似Some(Map("test" -> List(324)))的东西,所以下面是代码的外观。

如果asFormUrlEncoded可能返回None,而您没有任何处理方法,那么您应该防范它:

val a = Some(Map("test" -> List(324)))
val value = a match {
  case Some(m) => m.collect { case (k, List(v)) => k -> v }
  case None => sys.error("expected something, got nothing")
}

如果你确信asFormUrlEncoded已经返回Some,那么你可以这样做:

val a = Some(Map("test" -> List(324)))
val Some(value) = a.map(_.collect { case (k, List(v)) => k -> v })

最新更新