映射地图的单个条目

zig*_*tar 5 collections scala scalaz

我希望实现以下内容:

(_ : Map[K,Int]).mapKey(k, _ + 1)
Run Code Online (Sandbox Code Playgroud)

并且该mapKey函数仅将第二个参数(Int => Int)应用于存储在其下的值k.标准库中有什么东西吗?如果不是我打赌Scalaz中有什么东西.

当然我可以自己编写这个函数(m.updated(k,f(m(k)))并且这样做很简单.但是我已经多次遇到这个问题,所以也许它已经完成了?

对于Scalaz,我想象下面的代码:

(m: Map[A,B]).project(k: A).map(f: B => B): Map[A,B]
Run Code Online (Sandbox Code Playgroud)

Deb*_*ski 3

你当然可以添加

\n\n
def changeForKey[A,B](a: A, fun: B => B): Tuple2[A, B] => Tuple2[A, B] = { kv =>\n  kv match {\n    case (`a`, b) => (a, fun(b))\n    case x => x\n  }\n}\n\nval theMap = Map('a -> 1, 'b -> 2)\ntheMap map changeForKey('a, (_: Int) + 1)\nres0: scala.collection.immutable.Map[Symbol,Int] = Map('a -> 2, 'b -> 2)\n
Run Code Online (Sandbox Code Playgroud)\n\n

但这会规避有关内存重用和访问的任何优化。

\n\n

我还为您提出的方法提出了一个相当冗长且低效的 scalaz 解决方案,使用拉链project

\n\n
theMap.toStream.toZipper.flatMap(_.findZ(_._1 == 'a).flatMap(elem => elem.delete.map(_.insert((elem.focus._1, fun(elem.focus._2)))))).map(_.toStream.toMap)\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者

\n\n
(for {\n  z <- theMap.toStream.toZipper\n  elem <- z.findZ(_._1 == 'a)\n  z2 <- elem.delete\n} yield z2.insert((elem.focus._1, fun(elem.focus._2)))).map(_.toStream.toMap)\n
Run Code Online (Sandbox Code Playgroud)\n\n

可能用处不大。我\xe2\x80\x99m 只是发布供参考。

\n