且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

根据以前的值更新地图中的值的惯用方式

更新时间:2022-10-17 23:02:21

中没有调整 API,不幸的是。我有时使用像以下这样的功能(在Haskell的 Data.Map.adjust ,具有不同的参数顺序):

  def adjust [A,B](m:Map [A​​,B],k:A)(f:B => B)= m.updated(k,f(m(k)))

现在 adjust(m,Mark)(_ - 50)做你想要的您还可以使用 pimp-my-library模式获得更自然的 m.adjust(Mark)(_ - 50)语法,如果你真的想要一些更清洁的东西。



(注意如果 k 不在地图中,与Haskell行为不同,也可能是您想要在实际代码中修复的内容,上述短版本会抛出异常。)


Let's say I store bank accounts information in an immutable Map:

val m = Map("Mark" -> 100, "Jonathan" -> 350, "Bob" -> 65)

and I want to withdraw, say, $50 from Mark's account. I can do it as follows:

val m2 = m + ("Mark" -> (m("Mark") - 50))

But this code seems ugly to me. Is there better way to write this?

There's no adjust in the Map API, unfortunately. I've sometimes used a function like the following (modeled on Haskell's Data.Map.adjust, with a different order of arguments):

def adjust[A, B](m: Map[A, B], k: A)(f: B => B) = m.updated(k, f(m(k)))

Now adjust(m, "Mark")(_ - 50) does what you want. You could also use the pimp-my-library pattern to get the more natural m.adjust("Mark")(_ - 50) syntax, if you really wanted something cleaner.

(Note that the short version above throws an exception if k isn't in the map, which is different from the Haskell behavior and probably something you'd want to fix in real code.)