在 Scala 匿名函数中是否有更简洁的模式匹配方法?

发布于 2024-11-17 00:50:32 字数 277 浏览 1 评论 0原文

我发现自己编写如下代码:

val b = a map (entry =>
    entry match {
        case ((x,y), u) => ((y,x), u)
    }
)

如果可行的话,我想以不同的方式编写它:

val c = a map (((x,y) -> u) =>
    (y,x) -> u
)

有什么方法可以得到接近于此的东西吗?

I find myself writing code like the following:

val b = a map (entry =>
    entry match {
        case ((x,y), u) => ((y,x), u)
    }
)

I would like to write it differently, if only this worked:

val c = a map (((x,y) -> u) =>
    (y,x) -> u
)

Is there any way I can get something close to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

來不及說愛妳 2024-11-24 00:50:32

不管你相信与否,这确实有效:

val b = List(1, 2)
b map {
  case 1 => "one"
  case 2 => "two"
}

您可以跳过 p =>; p match 在简单情况下。所以这应该有效:

val c = a map {
  case ((x,y) -> u) => (y,x) -> u
}

Believe it or not, this works:

val b = List(1, 2)
b map {
  case 1 => "one"
  case 2 => "two"
}

You can skip the p => p match in simple cases. So this should work:

val c = a map {
  case ((x,y) -> u) => (y,x) -> u
}
惟欲睡 2024-11-24 00:50:32

在您的示例中,您可能需要三种略有不同的语义。

  1. 映射集合,转换与模式匹配的每个元素。如果任何元素不匹配,则抛出异常。这些语义是通过

    实现的

    val b = a map { case ((x, y), u) =>; ((y,x),u) }
    
  2. 集合上的

    Map 来实现的,转换与模式匹配的每个元素。默默地丢弃不匹配的元素:

    val b = acollect { case ((x, y), u) =>; ((y,x),u) }
    
  3. 映射集合,安全地解构然后转换每个元素。这些是我期望像

    这样的表达式的语义

    val b = 地图 (((x, y), u) => ((y, x), u)))  
    

    不幸的是,Scala 中没有简洁的语法来实现这些语义。
    相反,你必须解构自己:

    val b = 地图 { p =>; ((p._1._2, p._1._1), p._2) }
    

    人们可能会想使用值定义来进行解构:

    val b = 地图 { p =>; val ((x,y), u) = p; ((y,x),u) }
    

    但是,此版本并不比使用显式模式匹配的版本更安全。因此,如果您想要安全的解构语义,最简洁的解决方案是显式键入您的集合以防止意外扩大并使用显式模式匹配:

    val a: List[((Int, Int), Int)] = // ...
    // ...
    val b = 地图 { case ((x, y), u) => ((y,x),u) }
    

    如果a的定义与其使用相距甚远(例如在单独的编译单元中),您可以通过在映射调用中指定其类型来最大程度地降低风险:

    val b = (a: List[((Int, Int), Int)]) map { case ((x, y), u) =>; ((y,x),u) }
    

In your example, there are three subtly different semantics that you may be going for.

  1. Map over the collection, transforming each element that matches a pattern. Throw an exception if any element does not match. These semantics are achieved with

    val b = a map { case ((x, y), u) => ((y, x), u) }
    
  2. Map over the collection, transforming each element that matches a pattern. Silently discard elements that do not match:

    val b = a collect { case ((x, y), u) => ((y, x), u) }
    
  3. Map over the collection, safely destructuring and then transforming each element. These are the semantics that I would expect for an expression like

    val b = a map (((x, y), u) => ((y, x), u)))  
    

    Unfortunately, there is no concise syntax to achieve these semantics in Scala.
    Instead, you have to destructure yourself:

    val b = a map { p => ((p._1._2, p._1._1), p._2) }
    

    One might be tempted to use a value definition for destructuring:

    val b = a map { p => val ((x,y), u) = p; ((y, x), u) }
    

    However, this version is no more safe than the one that uses explicit pattern matching. For this reason, if you want the safe destructuring semantics, the most concise solution is to explicitly type your collection to prevent unintended widening and use explicit pattern matching:

    val a: List[((Int, Int), Int)] = // ...
    // ...
    val b = a map { case ((x, y), u) => ((y, x), u) }
    

    If a's definition appears far from its use (e.g. in a separate compilation unit), you can minimize the risk by ascribing its type in the map call:

    val b = (a: List[((Int, Int), Int)]) map { case ((x, y), u) => ((y, x), u) }
    
追风人 2024-11-24 00:50:32

在您引用的示例中,最干净的解决方案是:

val xs = List((1,2)->3,(4,5)->6,(7,8)->9)
xs map { case (a,b) => (a.swap, b) }

In your quoted example, the cleanest solution is:

val xs = List((1,2)->3,(4,5)->6,(7,8)->9)
xs map { case (a,b) => (a.swap, b) }
拿命拼未来 2024-11-24 00:50:32
val b = a map { case ((x,y), u) => ((y,x), u) }
val b = a map { case ((x,y), u) => ((y,x), u) }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文