Scala 允许这种提取器吗?

发布于 2024-11-24 09:19:06 字数 405 浏览 2 评论 0原文

假设我有这个集合:

val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))

有没有一种方法可以定义一个提取器,它可以按以下方式工作:

a.foreach(e => {
   e match {
      case Array( ending with 5 ) => 
      case _ =>
   }
})

抱歉伪代码,但我不知道如何表达它。有没有办法匹配最后一个元素为 5 的内容?如果我想匹配第一个元素为 1、最后一个元素为 5 的内容该怎么办?这是否适用于各种长度的数组(请注意,我在示例中专门为数组选择了不同的长度)。

谢谢!

Let's say I have this collection:

val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))

Is there a way to define an extractor which would work in the following way:

a.foreach(e => {
   e match {
      case Array( ending with 5 ) => 
      case _ =>
   }
})

Sorry for the pseudocode, but I don't know how to express it. Is there a way to match something having 5 as the last element? What if I would want to match something having a 1 as the first element and a 5 as the last? Could this work for arrays of various lengths ( note that I specifically chose different lengths for my arrays in the example ).

Thanks!

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

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

发布评论

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

评论(4

奈何桥上唱咆哮 2024-12-01 09:19:06

是的,您可以:

object EndsWith {
  def unapply[A]( xs: Array[A] ) = 
    if( xs.nonEmpty ) Some( xs.last ) else None
}

在您的示例中:

val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))

a foreach { 
  case e @ EndsWith(5) => println( e.mkString("(",",",")" ) )
  case _ =>
}

它按预期打印 (1,2,3,4,5)(4,5)(5)

使用相同的方法,您可以编写一个提取器 StartWith,然后添加一个方法将它们组合到一个匹配这两个条件的新提取器中。

Yes you can:

object EndsWith {
  def unapply[A]( xs: Array[A] ) = 
    if( xs.nonEmpty ) Some( xs.last ) else None
}

On your example:

val a = Array(Array(1,2,3,4,5),Array(4,5),Array(5),Array(1,2,6,7,8))

a foreach { 
  case e @ EndsWith(5) => println( e.mkString("(",",",")" ) )
  case _ =>
}

It prints as expected (1,2,3,4,5), (4,5) and (5)

With the same approach, you could write an extractor StartWith and then add a method to combine them in a new extractor matching both conditions.

旧伤慢歌 2024-12-01 09:19:06
a.foreach(e => {
   e match {
      case a: Array[Int] if a.last == 5 => 
      case _ =>
   }
})

您可以做一些更好的事情来匹配第一个元素:

a.foreach(e => {
   e match {
      case Array(1, _*) => 
      case _ => 
   }
})

不幸的是,@_* 必须是数组参数列表中的最后一项。但您可以根据需要使之前的匹配变得尽可能复杂。

scala> val Array(1, x @_*) = Array(1,2,3,4,5)
x: Seq[Int] = Vector(2, 3, 4, 5)

scala> val Array(1, b, 3, x @_*) = Array(1,2,3,4,5)
b: Int = 2
x: Seq[Int] = Vector(4, 5)
a.foreach(e => {
   e match {
      case a: Array[Int] if a.last == 5 => 
      case _ =>
   }
})

You can do something a little better for matching on the first elements:

a.foreach(e => {
   e match {
      case Array(1, _*) => 
      case _ => 
   }
})

Unfortunately the @_* thing has to be the last item in the list of array arguments. But you can make the matching before that as complex as you want.

scala> val Array(1, x @_*) = Array(1,2,3,4,5)
x: Seq[Int] = Vector(2, 3, 4, 5)

scala> val Array(1, b, 3, x @_*) = Array(1,2,3,4,5)
b: Int = 2
x: Seq[Int] = Vector(4, 5)
旧街凉风 2024-12-01 09:19:06

case 语法支持 if,因此这样可以工作:

a foreach {
  case a: Array[Int] if a.last == 5 =>
  case _ =>
}

The case syntax supports ifs, so this would work:

a foreach {
  case a: Array[Int] if a.last == 5 =>
  case _ =>
}
¢蛋碎的人ぎ生 2024-12-01 09:19:06
a.foreach (ar => ar.last match {                    
  case 5 => println ("-> 5] " + ar.mkString ("~"))
  case _ => println ("   ?] " + ar.mkString (":")) }) 

为什么不直接匹配最后一个元素?

-> 5] 1~2~3~4~5
-> 5] 4~5
-> 5] 5
   ?] 1:2:6:7:8
a.foreach (ar => ar.last match {                    
  case 5 => println ("-> 5] " + ar.mkString ("~"))
  case _ => println ("   ?] " + ar.mkString (":")) }) 

Why don't you match directly for the last element?

-> 5] 1~2~3~4~5
-> 5] 4~5
-> 5] 5
   ?] 1:2:6:7:8
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文