Scala使用模式匹配获取List的第一个和最后一个元素

时间:2011-07-14 17:45:43

标签: scala functional-programming pattern-matching

我在列表上进行模式匹配。无论如何我可以访问列表的第一个和最后一个元素进行比较吗?

我想做点什么......

case List(x, _*, y) if(x == y) => true

case x :: _* :: y =>

或类似的东西...... 其中xy是列表的第一个和最后一个元素..

我怎么能这样做......任何想法?

4 个答案:

答案 0 :(得分:24)

使用scala.collection包中的标准:++:提取器


原始回答

定义自定义提取器对象。

object :+ {
  def unapply[A](l: List[A]): Option[(List[A], A)] = {
    if(l.isEmpty)
      None
    else 
      Some(l.init, l.last)
  }
}

可以用作:

val first :: (l :+ last) = List(3, 89, 11, 29, 90)
println(first + " " + l + " " + last) // prints 3 List(89, 11, 29) 90

(对于您的情况:case x :: (_ :+ y) if(x == y) => true

答案 1 :(得分:16)

万一你错过了显而易见的事情:

case list @ (head :: tail) if head == list.last => true

head::tail部分在那里,因此您在空列表中不匹配。

答案 2 :(得分:8)

简单地:

case head +: _ :+ last => 

例如:

scala> val items = Seq("ham", "spam", "eggs")
items: Seq[String] = List(ham, spam, eggs)

scala> items match {
     |   case head +: _ :+ last => Some((head, last))
     |   case List(head) => Some((head, head))
     |   case _ => None
     | }
res0: Option[(String, String)] = Some((ham,eggs))

答案 3 :(得分:0)

让我们理解与此问题相关的概念,“ ::”,“ +:”和“:+”之间有区别:

第一运营商

' :: '-是右关联运算符,专门用于列表

scala> val a :: b :: c = List(1,2,3,4)
a: Int = 1
b: Int = 2
c: List[Int] = List(3, 4)

第二个操作员

' +:'-也是右关联运算符,但它适用于seq,而不仅仅是列表。

scala> val a +: b +: c = List(1,2,3,4)
a: Int = 1
b: Int = 2
c: List[Int] = List(3, 4)

第三运算符

':+ '-也是左关联运算符,但它对seq起作用,它比列表更通用

scala> val a :+ b :+ c = List(1,2,3,4)
a: List[Int] = List(1, 2)
b: Int = 3
c: Int = 4
  

操作员的关联性取决于操作员的最后一个字符。以冒号“:”结尾的运算符是右关联的。所有其他运算符都是左关联的。

     

左关联二进制操作e1; op; e2解释为e1.op(e2)

     

如果op是 right-associative ,则将同一操作解释为{val x = e1; e2.op(x)},其中x是新名称。

现在回答您的问题: 因此,现在,如果您需要从列表中获取第一个和最后一个元素,请使用以下代码

scala> val firstElement +: b :+ lastElement = List(1,2,3,4)
firstElement: Int = 1
b: List[Int] = List(2, 3)
lastElement: Int = 4