简体   繁体   中英

How to delete key from Map in Option Scala

Say i have case classes like this.

case class someClass0(content: someClass1)

case class someClass1(someContent: Option[Map[String, someClass2]])

case class someClass2(someKey: Array[Int])

I need to delete items in Map(which is immutable) by values.

This values i get through iteration.

  val keys_to_remove = new ListBuffer[String]()
  val keys_to_keep: List[Int] = List(100, 200)
  for (x <- keys_to_keep) {
    content.someContent.get.foreach {
      case (key: String, value: someClass2) => {
        if (!value.someKey.contains(x)) {
          keys_to_remove.append(key)
        }
      }
    }
  }

So, how to keep all the structure, and delete only needed items by key?

I was trying to change type of Map like

content.someContent.map(_.to(collection.mutable.Map))

But content.someContent.get.remove(key) is not working. What am i doing wrong?

You don't need mutability for that.

val keys_to_keep: List[String] = List("a", "b")

val res = content.someContent.map(
  _.filterKeys(k => !keys_to_keep.contains(k))
)

filterKeys filters a Map by testing each entries' key against a condition.


Of course, it is important to remember that you can't test contains on a List[Int] against Strings , as the result will always be false.


Furthermore, try looking up style-guides for Scala:

  • Classes are usually named in upper camel case
  • Values and variables are usually named in lower camel case

Try it out

You can do it using - operator and foldLeft on keys to remove.

you are using get for get value, if you want do it safety, you need to use:

content.someContent.map(immutableMap => 
  keys_to_remove.foldLeft(immutableMap){
    (map, key) =>
      map - key
}).getOrElse(Map.empty[String, SomeClass2])

this works like in this example:

import scala.collection.mutable.ListBuffer
val immutableMap = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
val keys_to_remove: ListBuffer[String] = ListBuffer("b", "d")
println(immutableMap) // Map(a -> 1, b -> 2, c -> 3, d -> 4)
val mapWithoutKeys = keys_to_remove.foldLeft(immutableMap){
  (map, key) =>
    map - key
}
println(mapWithoutKeys) //Map(a -> 1, c -> 3)

Here's how you can do it:

val optionalMap = someClass0.content.someContent.map {
  contentMap => contentMap - keyToBeRemoved
}

val originalStructure = someClass0.copy(content = SomeClass1(optionalMap))

Here's the Scastie

This will remove all keys and keep structure

val someClass0_copy = someClass0.copy(content = Content(someContent = someClass0.content. someContent.map(_.removedAll(keysToRemove)))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM