【问题标题】:How to delete key from Map in Option Scala如何在 Option Scala 中从 Map 中删除键
【发布时间】:2020-08-04 05:44:24
【问题描述】:

假设我有这样的案例类。

case class someClass0(content: someClass1)

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

case class someClass2(someKey: Array[Int])

我需要按值删除 Map(不可变)中的项目。

这个值是我通过迭代得到的。

  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)
        }
      }
    }
  }

那么,如何保留所有结构,只删除需要的项目呢?

我试图改变地图的类型

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

但是content.someContent.get.remove(key) 不起作用。 我做错了什么?

【问题讨论】:

    标签: scala scala-collections


    【解决方案1】:

    你不需要可变性。

    val keys_to_keep: List[String] = List("a", "b")
    
    val res = content.someContent.map(
      _.filterKeys(k => !keys_to_keep.contains(k))
    )
    

    filterKeys 通过根据条件测试每个条目的键来过滤Map


    当然,重要的是要记住,您不能在 List[Int] 上针对 Strings 测试 contains,因为结果总是错误的。


    此外,尝试查找 Scala 的样式指南:

    • 类通常以大写骆驼命名
    • 值和变量通常以小写骆驼命名

    Try it out

    【讨论】:

    • 我得到了一些(地图视图())((((
    • @MakarNikitin 这意味着您的Map 正在使用MapView 实现。这是一个惰性实现,在您实际查询它们之前不会产生结果(例如使用.apply(key))。
    【解决方案2】:

    您可以使用 - 运算符和 foldLeft 键删除。

    您正在使用get 获取价值,如果您想安全地进行操作,您需要使用:

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

    这就像在这个例子中一样:

    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)
    

    【讨论】:

    • 但我不仅有 Map,还有 Option[Map]。我试过val mapWithoutKeys = keys_to_remove.foldLeft(content.someContent.get) 得到HashMap()
    【解决方案3】:

    你可以这样做:

    val optionalMap = someClass0.content.someContent.map {
      contentMap => contentMap - keyToBeRemoved
    }
    
    val originalStructure = someClass0.copy(content = SomeClass1(optionalMap))
    

    这是Scastie

    【讨论】:

    • 我不仅需要过滤地图,还需要所有父结构。
    • @MakarNikitin 我已经更新了我的答案以及 Scastie 的链接。
    【解决方案4】:

    这将删除所有键并保留结构

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

    【讨论】:

      猜你喜欢
      • 2017-03-22
      • 2014-03-24
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 2019-02-13
      • 1970-01-01
      相关资源
      最近更新 更多