-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Map#updateWith to modify a map based on current value #7320
Conversation
* | ||
* @param key the key value | ||
* @param remappingFunction the function to compute a new mapping | ||
* @tparam V1 the type of newly computed value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
V1
does not appear to be used here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, removed.
d6f09d1
to
3f68a43
Compare
I’m not sure |
If it serves as an inspiration, in a Haskell library there is a similar method called |
IMO, this method should have a name that differ from
|
An interesting question is whether or not the argument should be a function (as it is now) or partial function (as it is in collection-contrib, linked by @julienrf) |
I don't think we should call it I think |
what are the arguments either way? P.S. needs rebase |
Version with a partial functionDefinition site: def updatedWith(key: K)(pf: PartialFunction[Option[V], Option[V]]): Map[K, V] Call site: map.updatedWith("foo") { case Some(previous) => Some(previous * 2) } Version with a total functionDefinition site: def updatedWith(key: K)(pf: Option[V] => Option[V]): Map[K, V] Call site: map.updatedWith("foo") {
case Some(previous) => Some(previous * 2)
case None => None
} The version with a partial function has a more complex type signature, but allows users to write less code at use site. Conversely, the version with a total function has a simpler type signature but requires users to always specify the cases they want to ignore. Both versions are fine to me. |
I agree with @julienrf - both are fine to me as well. I have a weak preference for the one which uses a |
I am okay with |
I rebased the PR and renamed Total function is used instead of |
val previousValue = this.get(key) | ||
val nextValue = remappingFunction(previousValue) | ||
(previousValue, nextValue) match { | ||
case (None, None) => this.asInstanceOf[CC[K,V1]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.asInstanceOf[CC[K,V1]]
should be coll
val nextValue = remappingFunction(previousValue) | ||
(previousValue, nextValue) match { | ||
case (None, None) => this.asInstanceOf[CC[K,V1]] | ||
case (Some(_), None) => this.remove(key).asInstanceOf[CC[K,V1]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had a similar case recently. It would be good to restrict C <: CC[K, V]
to get rid of this cast. I think I tried such a change a while ago but ran into some problems. It's worth another try.
@exoego Would you have some time to address the last reviews? |
I took several hours but still could not fix generics constraints. I think It is too complex for non-expert of scala collections. |
Yes, ignore the type bounds. I gave it another try and didn't get any further than #7504. See my comments there on what the remaining problems are. |
I merged the updated version in #7517 |
Addresses scala/bug#11185 by adding the following methods that is analogus to
java.util.Map.compute
computeupdateWith
computedupdatedWith
concurrent.Map
Option[V]
Map[K,V]