Scala 地图合并功能的改进
我正在写一个函数来合并两个地图。这就是我到目前为止所做的:Scala 地图合并功能的改进,scala,Scala,我正在写一个函数来合并两个地图。这就是我到目前为止所做的: def merge[K, V1, V2, V3](left: Map[K, V1], right: Map[K, V2]) (fn: (Option[V1], Option[V2]) => V3): Map[K, V3] = { val r = (left.keySet ++ right.keySet) map { key => (key -> fn(left.get(key), rig
def merge[K, V1, V2, V3](left: Map[K, V1], right: Map[K, V2])
(fn: (Option[V1], Option[V2]) => V3): Map[K, V3] = {
val r = (left.keySet ++ right.keySet) map {
key =>
(key -> fn(left.get(key), right.get(key)))
}
r.toMap
}
该函数本身起作用。您可以按如下方式使用该函数:
val m1 = Map(1 -> "one", 3 -> "three", 5 -> "five")
val m2 = Map(1 -> "I", 5 -> "V", 10 -> "X")
merge(m1, m2) { (_, _) }
// returns:
// Map(1 -> (Some(one),Some(I)),
// 3 -> (Some(three),None),
// 5 -> (Some(five),Some(V)),
// 10 -> (None,Some(X)))
我有两个问题:
.get
和.toMap
调用的性能和计算复杂性。有人能改进实施吗{({,{)}
)。我不能很好地理解语法虽然我最初说的是性能,但我指的是计算复杂性。我猜这个函数在O(n•ln(n))时间内执行。看起来我的函数在O(n)中大致执行。可以在O(ln(n))中完成吗?对于默认函数文本使用:
(fn: (Option[V1], Option[V2]) => V3 =
(x: Option[V1], y: Option[V2]) => Tuple2(x,y))
您必须像这样使用merge:merge(m1,m2)(
我想说的是,在对实际数据进行一些测量之前,不要担心性能
编辑:关于性能,通过提供一个视图而不是构建一个映射,您可以以查找为代价快速“构建”——假设我们处理的是不可变映射。因此,根据实际数据和用例,您可以为某些操作获得更好的性能,但这需要权衡
class MergedView[K, V1, V2, V3](
left: Map[K, V1], right: Map[K, V2]
)(fn: (Option[V1], Option[V2]) => V3 = (x: Option[V1], y: Option[V2]) => Tuple2(x,y)
) extends collection.DefaultMap[K, V3] {
def get(key: K): Option[V3] = (left.get(key), right.get(key)) match {
case (None, None) => None
case t => Some(fn(t._1, t._2))
}
lazy val tuples = (left.keys ++ right.keys).map(key => key -> get(key).get)
def iterator: Iterator[(K, V3)] = tuples.iterator
}
val r1 = new MergedView(m1, m2)() // use parens here for second param list.
您不应该担心
get
——是的,它会创建一个包装器对象,但是做任何其他事情都会很尴尬,除非分析器显示这是一个问题,否则您不应该尝试
至于toMap
,是的,这可能会让你慢下来。您可以尝试使用
关于
get
和toMap
的复杂性,查找和添加是不可变HashMap
的有效常量时间,这是默认的Map
。参见。回答问题1:您可以看看Scalaz的地图幺半群类型类,如Eric Torreberre所述。你的问题有点不同,但它可能会给你一些想法。请看上面的例子。@Kipton地图幺半群令人印象深刻。我必须考虑一下这是否适用。我不太担心创建包装器对象(我无论如何都需要)的性能,而担心n次调用O(ln(n))函数的性能。@dave查找(即,get
)对于默认映射(HashMap)来说是有效的常量时间(取决于哈希质量)。请参阅Scala系列的详细信息。优秀的链接!我一直在寻找类似的东西。从来没有想过要创建一个视图对象。非常有趣!这对我的用例没有帮助,但我会在将来记住这一点。huynhjl这太棒了@戴夫,我被你的回答搞糊涂了,因为这不是一个通用的解决方案。我可以用…将视图转换回地图。。。r1。toMap@huynhjl,我如何将我自己的密钥排序引入到这个中?谢谢。@Core-我已经忘了为什么它在我的特殊情况下不起作用。