Scala:当两个项目之一满足某些条件时进行模式匹配

2024-03-07

我经常编写比较两个对象的代码,并根据它们是否相同或不同(根据它们的不同之处)生成一个值。

所以我可能会写:

val result = (v1,v2) match {
  case (Some(value1), Some(value2)) => "a"
  case (Some(value), None)) => "b"
  case (None, Some(value)) => "b"
  case _ = > "c"
}

第二个和第三个案例实际上是相同的,所以我尝试写:

val result = (v1,v2) match {
  case (Some(value1), Some(value2)) => "a"
  case (Some(value), None)) || (None, Some(value)) => "b"
  case _ = > "c"
}

但没有运气。

我在几个地方遇到这个问题,这只是一个具体的例子,更一般的模式是我有两件事,我想知道其中是否只有一个满足某个谓词,所以我想写像这样的东西:

val result = (v1,v2) match {
  case (Some(value1), Some(value2)) => "a"
  case OneAndOnlyOne(value, v: Option[Foo] => v.isDefined ) => "b"
  case _ = > "c"
}

所以这里的想法是 OneAndOnlyAve 可以配置一个谓词(在本例中是 Defined ),并且您可以在多个地方使用它。

上面的代码根本不起作用,因为它是向后的,谓词需要传递到提取器中而不是返回。

像这样的事情怎么样?

val result = (v1,v2) match {
  case (Some(value1), Some(value2)) => "a"
  case new OneAndOnlyOne(v: Option[Foo] => v.isDefined )(value) => "b"
  case _ = > "c"
}

with:

class OneAndOnlyOne[T](predicate: T => Boolean) {
  def unapply( pair: Pair[T,T] ): Option[T] = {
    val (item1,item2) = pair
    val v1 = predicate(item1)
    val v2 = predicate(item2)

    if ( v1 != v2 )
      Some( if ( v1 ) item1 else item2 )
    else
      None
  }
}

但是,这不能编译。

任何人都可以找到使该解决方案发挥作用的方法吗?或者提出另一种解决方案?我可能让这件事变得更加复杂:)


我认为您在问两个略有不同的问题。

一个问题是如何在 switch 语句中使用“or”。 ||不起作用; |做。在这种情况下,您不能使用变量(因为通常它们可能匹配不同的类型,这会使类型变得混乱)。所以:

def matcher[T](a: (T,T)) = {
  a match {
    case (Some(x),Some(y)) => "both"
    case (Some(_),None) | (None,Some(_)) => "either"
    case _ => "none"
  }
}

另一个问题是如何避免一遍又一遍地执行此操作,特别是如果您希望能够获取元组中的值。我在这里为 Option 实现了一个版本,但您可以使用未包装的元组和布尔值。

实现此目的的一个技巧是,在开始匹配值之前预先包装值,然后使用您自己的匹配结构来执行您想要的操作。例如,

class DiOption[+T] {
  def trinary = this
}
case class Both[T](first: T, second:T) extends DiOption[T] { }
case class OneOf[T](it: T) extends DiOption[T] { }
case class Neither() extends DiOption[Nothing] { }
implicit def sometuple2dioption[T](t2: (Option[T],Option[T])): DiOption[T] = {
  t2 match {
    case (Some(x),Some(y)) => Both(x,y)
    case (Some(x),None) => OneOf(x)
    case (None,Some(y)) => OneOf(y)
    case _ => Neither()
  }
}

// Example usage
val a = (Some("This"),None)
a trinary match {
  case Both(s,t) => "Both"
  case OneOf(s) => "Just one"
  case _ => "Nothing"
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala:当两个项目之一满足某些条件时进行模式匹配 的相关文章

  • sbt:编译测试时设置特定的 scalacOptions 选项

    通常我使用这组选项来编译 Scala 代码 scalacOptions Seq deprecation encoding UTF 8 feature unchecked language higherKinds language impli
  • 具有动态命名参数的 Scala 案例类副本

    对于具有参数数量的 scala 案例类 21 e g case class Car type String brand String door Int 其中类型 吉普车 品牌 丰田 门 4 etc 还有一个复制方法允许使用命名参数覆盖 Ca
  • 在 scala 中保留推导的更高类型

    我有一个高阶类型 并致力于用它构建一些 DSL 我正在寻找一种方法来定义可以接受类型而无需显式指定此类型的函数 自我描述示例 class Wrap T val data T class DSL def doSomething T x Wra
  • 内存泄漏在哪里?

    我使用 InetAddress 来解析 IP 地址 但现在如果 IP 不可用 则需要存储主机名 所以我介绍了一个班级Host case class Host name String ip InetAddress import Host ad
  • 基于Java模式分割字符串

    您好 我有以下模式的日志文件 2014 03 06 03 21 45 432 ERROR mfs pool 3 thread 19 dispatcher StatusNotification Error processing notific
  • 手动排除sbt中的一些测试类

    我通常在 CI 中执行以下命令 清理更新编译测试发布 但是 我想从 sbt 命令行中排除 1 个 或几个 测试类 我怎样才能做到这一点 我不想更改我的代码以使用忽略等 两种可能的选择 test only See http www scala
  • 如何在cassandra中保存spark流数据

    构建 sbt以下是build sbt文件中包含的内容 val sparkVersion 1 6 3 scalaVersion 2 10 5 resolvers Spark Packages Repo at https dl bintray
  • Scala 条件列表构造

    我正在使用 Scala 2 9 2 并且想根据某些条件构建一个列表 考虑以下情况 其中 cond 是采用谓词 p 和类型 T 的值 在本例中为 t3 的某个函数 t1 t2 cond p t3 t4 我想要的行为如下 如果 p 为真 则应给
  • Scala 模式匹配打印漂亮

    是否有可能以某种方式编组部分函数 假设它总是只包含一种情况 进入某物人类可读的 假设我们有 Any 类型的集合 消息 List Any 以及使用模式匹配块定义的 PartialFuntion Any T 的数量 case object R1
  • Scala 中缺少多重集吗?

    我正在尝试 Scala 中的 Facebook Hacker Cup 2013 资格赛问题 对于第三个问题 我觉得需要一个有序的 Multiset 但在 scala 的 2 10 集合中找不到一个 scala 的集合中是否缺少此数据结构 会
  • 带可变参数的 Spark UDF

    如文档中所示 列出最多 22 个参数是唯一的选择吗 https spark apache org docs 1 5 0 api scala index html org apache spark sql UDFRegistration ht
  • akka-http:找不到参数解组的隐式值

    我的 Spray json 支持看起来像这样 object MarshallingSupport extends SprayJsonSupport implicit def json4sFormats Formats DefaultForm
  • 如何在Scala中表达这个类型?存在类型类(即隐式)限制吗?

    我正在使用 Play 框架的 JSON 库 它使用类型类来实现Json toJson功能 http www playframework org documentation api 2 0 4 scala index html play ap
  • 将 DOCTYPE 添加到 Scala XML 的最简单方法?

    我怎样才能在 Scala XML 中制作这个最小的 HTML5 p p 当然 在 Scala 中制作类似 HTML 的 XML 很简单 gt val html p p html scala xml Elem p p 但是 我怎样才能注入DO
  • Jack(Java Android 编译器套件)将如何影响 Scala 开发人员

    现在随着公告Jack https source android com source jack html谷歌阐明了 Java 与 Android 相关的可预见的未来 但这对 Scala 和其他基于 JVM 的语言开发人员有何影响 尤其 Sc
  • Map 和 Set 的实际类(不是抽象类,也不是特征类)是什么?

    在 Scala 中 映射和集合文字可以通过以下方式创建 val m Map 1 gt a 以及引用的类型m字面意思都是Map Int String 然而 scala文档表明Map实际上是一个特征 具有需要实现才能实例化的抽象成员 scala
  • 如何在每行中添加行号?

    假设这些是我的数据 Maps and Reduces are two phases of solving a query in HDFS Map is responsible to read data from input location
  • 与文件名中的冒号“:”作斗争

    我有以下代码 用于加载大量 csv gz 并将它们转储到其他文件夹中 并将源文件名作为一列 object DailyMerger extends App def allFiles path File List File val parts
  • 如果需要,Akka actor 可以从邮箱中删除消息吗?

    例如 如果我想从队列中删除冗余消息 这样当演员收到Connect消息 它应该检查它的邮箱并删除其他Connect消息 以便只进行一个连接而不是多个连接 这样的事情可能吗 是的 您可以将参与者调度程序配置为具有您选择的任何邮箱 因此如果您实现
  • Akka Stream - 根据 Flow 中的元素选择 Sink

    我正在使用 Akka 流创建一个简单的消息传递服务 该服务就像邮件递送一样 其中来自源的元素包括destination and content like case class Message destination String conte

随机推荐