在Scala中合并两个HashMaps
我需要创造
def MergeWith [Id,X,Y,Z](x:HashMap [Id,X],y:HashMap [Id,Y],f:(X,Y)=> Z):HashMap [Id,Z] 我想要: 1)迭代x 2)对于y中出现的键,将f(x [key],y [key])表示为结果:HashMap [Id,Z] 对于我发明的一切,我得到编译错误,我不明白如何战斗. 例如, def andWith[K,Z] (x: HashMap[K,y: HashMap[K,f: (X,Y) => Z): HashMap[K,Z] = { for { (x_name,x_value) <- x if y.contains(x_name) } yield x_name -> f(x_value,y.get(x_name)) } 产生 Error:(14,39) type mismatch; found : Option[Y] required: Y } yield x_name -> f(x_value,y.get(x_name)) ^ 这是可预测的,但我无法解开Option. 解决方法
以下是在Scala中编写此内容的非常简洁且合理的惯用方法:
def mergeWith[K,Z](xs: Map[K,ys: Map[K,Y]) (f: (X,Y) => Z): Map[K,Z] = xs.flatMap { case (k,x) => ys.get(k).map(k -> f(x,_)) } 请注意,我使用Map而不是HashMap,并且我稍微更改了一些标识符名称.我还将该函数放入其自己的参数列表中,这可以使语法对用户来说更加清晰. 这是非常密集的代码,所以我将解压缩一下.对于xs映射中的每个键值对(k,v),我们使用ys.get(k)得到一个Option [Y],如果键存在于ys中则为Some [Y],否则为None.我们使用Option上的map将内部的Y值(如果存在)更改为一对(K,Z). 因此,整个ys.get(k).map(k – > f(x,_))部分的值是Option [(K,Z)],它是恰好一对或零对的集合.如果我们在xs上使用了map,我们最终得到了Seq [Option [(K,Z)]],但是因为我们使用了flatMap,所以可以将它折叠成Map [K,Z],这就是我们想要的(以及我们指定的方法的返回类型. 我们可以尝试一下: scala> val mapX = Map('a -> 1,'b -> 2) mapX: scala.collection.immutable.Map[Symbol,Int] = Map('a -> 1,'b -> 2) scala> val mapY = Map('b -> "foo",'c -> "bar") mapY: scala.collection.immutable.Map[Symbol,String] = Map('b -> foo,'c -> bar) scala> mergeWith(mapX,mapY) { (x,y) => (x,y) } res0: Map[Symbol,(Int,String)] = Map('b -> (2,foo)) 这就是我们想要的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |