使用地图功能检索键时,将地图的元组键转换为另一张地图

时间:2019-10-22 11:11:30

标签: scala

运行以下代码时,我得到了一些意外的结果


val a = Map(
  ("1", "2") -> 1,
  ("1", "4") -> 2,
  ("2", "2") -> 3,
  ("2", "4") -> 4
)
println(a.size)
val b = a.map(_._1)
println(b.size)
val c = a.keySet
println(c.size)

结果是:

res0: Int = 4
b: scala.collection.immutable.Map[String,String] = Map(1 -> 4, 2 -> 4)
res1: Int = 2
c: scala.collection.immutable.Set[(String, String)] = Set((1,2), (1,4), (2,2), (2,4))
res2: Int = 4

我期望b的内容与c的相同。在Scala中可以期待吗?还是某种副作用?

2 个答案:

答案 0 :(得分:0)

我认为您想改用.keys,因为您是将Map [(String,String),Int]映射到Map [String,String],并且由于键必须是唯一的,因此其余的Map被丢弃。

发生这种情况是因为您正在映射到此Map [(String,String)],因此Scala转换为Map [String,String]

答案 1 :(得分:0)

是的,这是预期的行为。通常,Scala的collection map方法试图使输出集合与调用该方法的集合具有相同的类型。

因此,对于Map.map,每当您传递给Map的函数的结果类型为{{1时,输出集合 都可以是map }}。当您调用Tuple时,正是这种情况。此时,另一条规则开始起作用:val b = a.map(_._1)的键必须唯一。因此,当Scala在对Map的调用过程中遍历a时,会将a.map(_._1)的结果插入正在构建的新地图中(成为_._1)。第二个条目替换第一个条目,而第四个条目替换第三个条目,因为它们具有相同的密钥。

如果这不是您想要的行为,则应该能够通过将b的类型除以b以外的类型来解决该问题。

例如

Map