我在列表上进行模式匹配。无论如何我可以访问列表的第一个和最后一个元素进行比较吗?
我想做点什么......
case List(x, _*, y) if(x == y) => true
或
case x :: _* :: y =>
或类似的东西......
其中x
和y
是列表的第一个和最后一个元素..
我怎么能这样做......任何想法?
答案 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