我正在尝试撰写两张地图并在Scala中获取一张合成地图。我正在做以下事情:
val m1=Map(1->'A',2->'C',3->'Z')
val m2=Map('A' -> "Andy", 'Z'->"Zee",'D'->"David")
val m3=m2.compose(m1)
现在m3是m1; m2,但它的类型是Function1。
问题: 如何将Function1转换为Map?
PS。
Here,而不是m2.compose(m1),建议使用val m3 = m1 andThen m2
。无论如何,结果是Function1类型。
答案 0 :(得分:2)
您对不存在的密钥有何看法?如果你想从地图中删除这个值,请使用
val m1: Map[Int, Char] = Map(1 -> 'A', 2 -> 'C', 3 -> 'Z')
val m2: Map[Char, String] = Map('A' -> "Andy", 'Z' -> "Zee", 'D' -> "David")
val m3: Map[Int, String] = m1.filter(x => m2.contains(x._2)).map(x => x._1 -> m2(x._2))
//Map(1 -> Andy, 3 -> Zee)
跳过.filter(x => m2.contains(x._2))并为此情况抛出异常
答案 1 :(得分:1)
您也可以
val m3: Map[Int, String] = m1.mapValues(m2)
有一点需要注意,尽管有返回类型,但每次访问m2(m1(x))
时都会重新计算m3(x)
,就像m2.compose(m1)
一样。
因为我更新了问题的标题,答案现在没有直接解决问题主题。我将等待,看看是否有人可能提供直接答案(即,如何将Function1转换为映射)。
def funToMap[A, B](f: A => B): Map[A, B] = Map.empty[A, B].withDefault(f)
答案 2 :(得分:0)
为什么编写两个地图会为您提供一个Function1
Map
提供Function1
的语义,然后提供一些语义。当您编写两个Map
函数时,会得到一个新的Function1
因为compose
是对函数的操作。
所以你不应期望通过撰写两个Map
得到Map
- 你只是在构成Map
的函数方面,而不是Map
自己。
如何获取合成地图
要将两个Map
实际组合成另一个Map
,您可以使用mapValues
,但要小心。如果你这样做:
val m3 = m1 mapValues m2
您将默默地获取视图(请参阅this bug)而不是简单的地图,因此当您在m3
中进行查找时,它会在m1
中进行查找,然后在{{ 1}}。对于大型m2
和少量查找,这是一个胜利,因为您没有处理很多您不需要的条目。但是如果你进行大量的查找,这可能会导致严重的性能问题。
要真正制作一个代表Map
和Map
组成的新单m1
数据结构,您需要执行类似
m2
这有点不幸。在一个完美的世界val m3 = (m1 mapValues m2).view.force
会给你新的单一组合m1 mapValues m2
- 并且很快就会创建一个形状与Map
相同但值为{{1}的新数据结构} - 和m1
会给你视图(类型会反映出来)。