在 Scala 中设计方便的默认值映射

2024-05-23

我发现自己使用了很多嵌套映射,例如 Map[Int、Map[String、Set[String]]],并且我希望在访问新密钥时自动创建新的 Map、Set 等。例如。像下面这样:

val m = ...
m(1992)("foo") += "bar"

请注意,如果不需要,我不想在此处使用 getOrElseUpdate,因为当您有嵌套映射并掩盖代码中实际发生的情况时,它会变得非常冗长:

m.getOrElseUpdate(1992, Map[String, Set[String]]()).getOrElseUpdate("foo", Set[String]()) ++= "bar"

所以我重写了 HashMap 的“默认”方法。我尝试了两种方法来做到这一点,但都不是完全令人满意。我的第一个解决方案是编写一个创建映射的方法,但似乎在声明变量时我仍然必须指定完整的嵌套映射类型,否则事情将不起作用:

scala> def defaultingMap[K, V](defaultValue: => V): Map[K, V] = new HashMap[K, V] {                      |   override def default(key: K) = {
 |     val result = defaultValue
 |     this(key) = result
 |     result
 |   }
 | }
defaultingMap: [K,V](defaultValue: => V)scala.collection.mutable.Map[K,V]

scala> val m: Map[Int, Map[String, Set[String]]] = defaultingMap(defaultingMap(Set[String]()))
m: scala.collection.mutable.Map[Int,scala.collection.mutable.Map[String,scala.collection.mutable.Set[String]]] = Map()

scala> m(1992)("foo") += "bar"; println(m)                                                    
Map(1992 -> Map(foo -> Set(bar)))

scala> val m = defaultingMap(defaultingMap(Set[String]()))
m: scala.collection.mutable.Map[Nothing,scala.collection.mutable.Map[Nothing,scala.collection.mutable.Set[String]]] = Map()

scala> m(1992)("foo") += "bar"; println(m)
<console>:11: error: type mismatch;
 found   : Int(1992)
 required: Nothing
       m(1992)("foo") += "bar"; println(m)
         ^

我的第二个解决方案是编写一个带有方法的工厂类,这样我只需声明每种类型一次。但是每次我想要一个新的默认值映射时,我都必须实例化工厂类,然后调用该方法,这看起来仍然有点冗长:

scala> class Factory[K] {                                       
 |   def create[V](defaultValue: => V) = new HashMap[K, V] {
 |     override def default(key: K) = {                     
 |       val result = defaultValue                          
 |       this(key) = result                                 
 |       result                                             
 |     }                                                    
 |   }                                                      
 | }                                                        
defined class Factory

scala> val m = new Factory[Int].create(new Factory[String].create(Set[String]()))
m: scala.collection.mutable.HashMap[Int,scala.collection.mutable.HashMap[String,scala.collection.mutable.Set[String]]] = Map()

scala> m(1992)("foo") += "bar"; println(m)
Map(1992 -> Map(foo -> Set(bar)))

我真的很想要像这样简单的东西:

val m = defaultingMap[Int](defaultingMap[String](Set[String]()))

有人看到有办法做到这一点吗?


对于 Scala 2.8:

object DefaultingMap {
  import collection.mutable
  class defaultingMap[K] {
    def apply[V](v: V): mutable.Map[K,V] = new mutable.HashMap[K,V] {
      override def default(k: K): V = {
        this(k) = v
        v
      }
    }
  }
  object defaultingMap {
    def apply[K] = new defaultingMap[K]
  }

  def main(args: Array[String]) {
    val d4 = defaultingMap[Int](4)
    assert(d4(3) == 4)
    val m = defaultingMap[Int](defaultingMap[String](Set[String]()))
    m(1992)("foo") += "bar"
    println(m)
  }
}

您无法在 Scala 中柯里化类型参数,因此需要使用类来捕获键类型的技巧。

顺便说一句:我认为生成的 API 不是很清楚。我特别不喜欢有副作用的地图访问。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Scala 中设计方便的默认值映射 的相关文章

  • 与嵌套泛型集合的混淆

    请帮助我理解为什么add1 and add4 报告错误以及原因add2 and add3 不 具体来说 请举例说明如果编译器允许其中每一个进行编译 则会产生不良后果的示例 class InnerTypeConfusion interface
  • 逆变方法参数类型

    wiki 逆变方法参数类型 https en wikipedia org wiki Covariance and contravariance 28computer science 29 Contravariant method argum
  • 宏:knownDirectSubclasses 被嵌套类型破坏?

    我有一个宏 它枚举密封特征的直接子类型 import scala reflect macros Context import language experimental macros object Checker def apply A U
  • 了解 Scala 中的中缀方法调用和缺点运算符(::)

    我对 Scala 编程语言相当陌生 当我遵循以下网站的讲义时 我正在尝试一些萦绕在我脑海中的东西 here http horstmann com sjsu cs152 04 closures1 html 我想我无法真正理解 cons 运算符
  • Scala 相当于 Java 的 Number

    我正在尝试为数值域类型构建类型层次结构 例如AYear is an Int 这是一个Number a Percentage is a Double 这是一个Number等等 我需要层次结构以便我可以调用toInt or toDouble关于
  • 如何抑制spark输出控制台中的“Stage 2===>”?

    我有数据帧并试图获取不同的计数并且能够成功获取不同的计数 但是每当 scala 程序执行时我都会收到此消息 Stage 2 gt 1 1 2 我如何在控制台中抑制特定的此消息 val countID dataDF select substr
  • 使用原始类型模拟案例类

    考虑以下类型结构 trait HasId T def id T case class Entity id Long extends HasId Long 比方说 我们想在一些测试中模拟实体类 val entityMock mock Enti
  • 通用特征的隐式转换

    我正在实现一个数据结构 并希望用户能够使用任何类型作为密钥 只要他提供一个合适的密钥类型来包装它 我有这个关键类型的特质 这个想法是进行从基类型到键类型的隐式转换 反之亦然 实际上 只使用基类型 该特征看起来像这样 trait Key T
  • 不支持的身份验证令牌,仅当禁用身份验证时才允许 schema='none':{ schema='none' } - Neo4j 身份验证错误

    我正在尝试使用 neo4j spark connector 从 Spark 连接到 Neo4j 当我尝试连接到 Neo4j 时遇到身份验证问题org neo4j driver v1 exceptions AuthenticationExce
  • Java ArrayList 和 HashMap 动态

    有人可以提供一个创建Java的例子吗ArrayList and HashMap在飞行中 所以而不是做一个add or put 实际上在类实例化时为数组 哈希提供种子数据 举个例子 类似于 PHP 的例子 array array 3 1 2
  • Scala Tuple2Zipped 与 IterableLike zip

    两种实现有什么区别 这个比那个好吗 有一篇博客文章说 Tuple2Zipped 性能更好 但没有提供原因 并且查看源代码我没有看到差异 val l1 List 1 2 3 val l2 List 5 6 7 val v1 l1 zip l2
  • 对 Scala Not Null 特征的库支持

    Notice 从 Scala 2 11 开始 NotNull已弃用 据我了解 如果您希望引用类型不可为空 则必须混合魔法NotNull特征 编译器会自动阻止你输入null 可以值在里面 看到这个邮件列表线程 http www nabble
  • 使用.Net/C# 计算集合的频率分布

    是否有一种快速 简单的方法来使用 Linq 或其他方式计算 Net 集合的频率分布 例如 任意长的 List 包含许多重复项 遍历列表并计算 跟踪重复次数的巧妙方法是什么 查找列表中重复项的最简单方法是将其分组 如下所示 var dups
  • scala play框架如何对异步控制器进行单元测试

    使用 Scala play 2 5 版并尝试遵循以下文档中的单元测试控制器指南 https www playframework com documentation 2 5 x ScalaTestingWithScalaTest https
  • 向 Scala Swing Panel 添加标签时出现类型不匹配错误

    我有这个课程扩展FlowPanel我正在尝试向其中添加标签 import java awt Label Color import scala swing import scala util Random class MyPanel exte
  • Akka Streams / HTTP:从响应中获取原始请求

    我有一个 Akka Streams 源 它会遍历流程并发布 HTTP 请求 source map toRequest via Http outgoingConnection host map toMessage 假设toRequest方法将
  • 如何定义与更高类型类型(类型构造函数)绑定的上下文

    我尝试过以下方法 def test Option T Ordering value1 Option T value2 Option T val e implicitly Ordering Option T compare value1 va
  • 使用 Scala 进行网页抓取 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何访问 Scala XML 中的父元素

    The scala xml包表示带有标记树节点的 XML 但是这棵树在 Scala 2 7 中是单向的吗 因为似乎没有办法访问Elem给定的父级Elem 这似乎同样适用于父母Document 例如 在 XOM 中你有getParent an
  • 关于 scala.math.Integral 的问题

    有什么方法mkNumericOps andmkOrderingOps of scala math Integral http www scala lang org api current scala math Integral html我们

随机推荐

  • 计算引擎启动脚本无法以非 root 用户身份执行

    将我的问题归结为最简单的情况 我使用带有以下启动脚本的 Compute Engine bin bash sudo useradd m drupal su drupal cd home drupal touch test txt 我可以确认
  • 错误类型 3 - 活动类不存在

    我正在尝试运行 webRTC 应用程序 但返回以下错误 启动应用程序 com onlinevoicecallapp com onlinevoicecallapp MainActivity 设备外壳命令 am start n com onli
  • 缺少嵌入互操作类型属性

    在一个 C 项目中 我收到以下警告 警告 CS1762 创建了对嵌入式互操作程序集 Interop SomeLibrary dll 的引用 因为间接引用了程序集 ALibraryOfMine dll 创建的该程序集 考虑更改任一程序集的 嵌
  • 将SQL数据引入jquery availabletag

    我正在尝试制作自动完成文本框 但如何将 SQL 数据包含到 jquery 可用标记并循环它 我无法根据以下代码执行该功能 任何帮助 将不胜感激 谢谢 这是我的预期输出 预期结果演示 http jsfiddle net VvETA 71 jq
  • Reactive Spring 不支持 HttpServletRequest 作为 REST 端点中的参数?

    我创建了一个 RestController 如下所示 RestController public class GreetingController RequestMapping value greetings method RequestM
  • PostgreSQL WHERE 计数条件

    我在 PostgreSQL 中有以下查询 SELECT COUNT a log id AS overall count FROM Log as a License as b WHERE a license id 7 AND a licens
  • CryptoJS 使用密码加密 AES,但 PHP 解密需要密钥

    我在用CryptoJS https code google com p crypto js AES加密字符串 function doHash msg msg String msg var passphrase aggourakia var
  • 获取 .wav 文件长度或持续时间

    我正在寻找一种方法来找出 python 中音频文件 wav 的持续时间 到目前为止我已经了解了 pythonwave图书馆 mutagen pymedia pymad我无法获取 wav 文件的持续时间 Pymad给了我持续时间 但它不一致
  • MongoDB中批量FindAndModify的解决方案

    我的用例如下 我在 mongoDB 中有一组文档 我必须发送这些文档进行分析 文件格式如下 id ObjectId 517e769164702dacea7c40d8 日期 1359911127494 状态 可用 其他字段 我有一个阅读器进程
  • ASP.NET MVC 站点中的覆盖视图不起作用

    我的解决方案中有一个单独的项目 其中包含一些控制器和编译的视图 我将这些控制器用作 MVC 应用程序中其他控制器的基类 并使用 RazorGenerator 编译视图 可以说B是具有非抽象操作方法的基本控制器一些动作返回视图 MyView
  • 新 Rails 应用程序出现问题

    我刚刚创建了一个新的rails应用程序 在CL上 使用rails new 我使用的是4 2 6 但似乎在我对应用程序执行任何操作之前我遇到了错误 first config environments development rb 53 in
  • 在另一个文件中扩展类的正确方法是什么?

    这就是我在 foo php 中的内容 class Foo public foo NULL public foo2 NULL public function setFoo foo foo2 this gt foo foo this gt fo
  • iOS5 和 Facebook API

    我想将我的应用程序与 Facebook 集成并从 github 下载 Facebook ios sdk 但是 该 sdk 适用于 Xcode 4 0 代码库 我正在使用 Xcode 4 2 for iOS 5 beta 5 应用程序 是否有
  • 带 Markdown 的两栏布局

    我正在编写并排文本 我必须用两列布局来准备这个 例如 一列包含英文文本 其他列 右列包含前面 英文 文本的翻译 Markdown 不支持表格标记 但 Github Flavored Markdown 支持 我做了一些尝试 但不幸的是无法解决
  • C 中是否可以动态定义结构体

    我很确定这最终将成为一个非常明显的问题 这就是为什么我没有找到太多关于它的信息 不过 我认为还是值得问一下 基本上 使用结构访问数据非常快 如果数据以一种可以立即作为结构进行处理的形式从网络中出来 那么从性能的角度来看 这是非常好的 但是
  • 计数排序的两种方法

    这是我的计数排序的两个实现 在这个非常简单的实现中 我所做的就是计算元素出现的次数 并在输出数组中插入与出现次数相同的次数 实施1 public class Simple static int a 5 6 6 4 4 4 8 8 8 9 4
  • 有没有办法让 jslint 在 javascript 的下一行中使用大括号?

    我改变了我的编码风格 function getParams entity use strict var accountID store getItem AccountID switch entity case Topic to functi
  • CSS 内边框?

    我纯粹用 CSS 创建了左侧的按钮 它是一个div 中的一个div 然而 右侧的三个按钮是background属性于img标签 我这样做是为了按照以下说明模拟翻转效果here http kyleschaeffer com best prac
  • Dplyr 过滤多个类似条件

    我正在尝试在 dplyr 中做一个过滤器 其中的列就像某些观察结果 我可以使用 sqldf 作为 Test lt sqldf select from database Where SOURCE LIKE ALPHA OR SOURCE LI
  • 在 Scala 中设计方便的默认值映射

    我发现自己使用了很多嵌套映射 例如 Map Int Map String Set String 并且我希望在访问新密钥时自动创建新的 Map Set 等 例如 像下面这样 val m m 1992 foo bar 请注意 如果不需要 我不想