2011-07-14 27 views
10

我正在做一個列表中的模式匹配。無論如何,我可以訪問列表的第一個和最後一個元素進行比較?Scala使用模式匹配獲取列表的第一個和最後一個元素

我想要做這樣的事情..

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

case x :: _* :: y =>

或類似的東西... 其中xy是列表的第一個和最後一個元素..

我該怎麼做..任何想法?

+0

從階2.10你可以只使用爲最後DEF最後[T](XS:序號[T])= {XS匹配{ 案例_:+ x => x }},請參閱https://issues.scala-lang.org/browse/SI-2575 –

回答

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

+0

整潔的解決方案。 Scala中的規則/技巧允許'(l:+ last)'與'(:+(l,last))'一樣工作?沒意識到這是可能的。 – overthink

+2

回答我自己的問題 - 似乎在這裏回答:http://stackoverflow.com/questions/1059145/how-is-this-case-class-match-pattern-working/1059161#1059161更多詳細信息在這裏:http ://www.artima.com/pins1ed/working-with-lists.html#16.5 – overthink

16

如果你錯過了很明顯的:

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

head::tail部分是有這麼你在空列表上不匹配。

5

簡單地:

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 _ => None 
    | } 
res0: Option[(String, String)] = Some((ham,eggs)) 
+0

這實際上不適用於具有一個元素的列表。爲此,你必須添加一個額外的案例。 –

相關問題