Skip to content
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

Consider a getAndRemove operation on Maps #86

Open
benhutchison opened this issue May 27, 2021 · 4 comments
Open

Consider a getAndRemove operation on Maps #86

benhutchison opened this issue May 27, 2021 · 4 comments
Labels

Comments

@benhutchison
Copy link

AFAIK, there isnt an easy way to get and remove an entry from a Map in a single lookup. remove removes it but doesnt expose the removed value. The desired operation would return a pair of the updated map, and the removed value (if any) wrapped in an Option.

In performance-critical code, a double lookup is not acceptable for something that can be readily done in a single visit to the map.

The operation can be performed in a single pass using updatedWith but the resulting code is non-obvious and involves a transient var. It's not the sort of code clients of the API should need to be writing.

@NthPortal
Copy link
Contributor

mutable.Map has remove(K):Option[V], even though the abstract method subtractOne(K):Map.this.type does not return the removed value.

I assume you're referring to immutable.Map, where the method removed(K):Map[K,V] returns a (potentially new) Map.
for immutable.Map, such a method would have to return (Map[K,V],Option[V]), which is not a super fun return type. still doable though

@NthPortal NthPortal added enhancement New feature or request library:collections labels Jul 7, 2021
@NthPortal
Copy link
Contributor

NthPortal commented Jul 8, 2021

it's worth noting that you can't gain efficiency from this change in scala-library-next. it doesn't have the ability to change implementations in the stdlib, so it would end up having to look up the value and then remove it separately anyway

@benhutchison
Copy link
Author

benhutchison commented Jul 8, 2021

As I mentioned above, it can be done in one pass using the existing updatedWith.

Here's an example (verbatim from my week3 solution of the Effective Scala course)

  def delete(id: Id): Boolean =
    var removed = Option.empty[Task]
    val tasks2 = loadTasks().toMap.updatedWith(id){
      case t@Some(task) => {removed = t; None}
      case None => None
    }
    saveTasks(Tasks(tasks2))
    removed.isDefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants