在Scala中将Function1转换为Map

时间:2015-06-25 16:05:55

标签: scala

我正在尝试撰写两张地图并在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类型。

3 个答案:

答案 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和少量查找,这是一个胜利,因为您没有处理很多您不需要的条目。但是如果你进行大量的查找,这可能会导致严重的性能问题。

要真正制作一个代表MapMap组成的新单m1数据结构,您需要执行类似

的操作
m2

这有点不幸。在一个完美的世界val m3 = (m1 mapValues m2).view.force 会给你新的单一组合m1 mapValues m2 - 并且很快就会创建一个形状与Map相同但值为{{1}的新数据结构} - 和m1会给你视图(类型会反映出来)。