5

假设我有这个集合:

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 的东西怎么办?这是否适用于各种长度的数组(请注意,我在示例中专门为我的数组选择了不同的长度)。

谢谢!

4

4 回答 4

11

是的你可以:

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,然后添加一个方法将它们组合到一个匹配两个条件的新提取器中。

于 2011-07-15T21:32:24.103 回答
9
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)
于 2011-07-15T20:05:24.980 回答
4

case语法支持ifs,所以这会起作用:

a foreach {
  case a: Array[Int] if a.last == 5 =>
  case _ =>
}
于 2011-07-15T20:10:09.440 回答
1
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
于 2011-07-15T23:07:44.070 回答