2011-07-14 10 views
10

Estoy haciendo un patrón que coincida en una lista. ¿De todos modos puedo acceder al primer y último elemento de la lista para comparar?Scala Get First y Last elements of List usando Pattern Matching

quiero hacer algo como ..

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

o

case x :: _* :: y =>

o algo similar ... donde x y y son elementos primero y el último de la lista ..

¿Cómo puedo hacer eso ... alguna idea?

+0

de Scala 2.10 sólo se puede utilizar para la última definición última [T] (xs: SEQ [T]) = {partido XS { case _: + x => x }}, consulte https://issues.scala-lang.org/browse/SI-2575 –

Respuesta

24

utilizan el estándar :+ y +: extractores de la scala.collection paquete


respuesta original

definir un objeto extractora personalizado.

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

Puede utilizarse como:

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

(para su caso: case x :: (_ :+ y) if(x == y) => true)

+0

Solución limpia. ¿Qué regla/truco en Scala permite que '(l: + last)' funcione igual que '(: + (l, last))'? No me di cuenta de que esto era posible. – overthink

+2

Respondiendo a mi propia pregunta - parece ser respondida aquí: http://stackoverflow.com/questions/1059145/how-is-case-class-match-pattern-working/1059161#1059161 con más detalles aquí: http : //www.artima.com/pins1ed/working-with-lists.html#16.5 – overthink

16

En caso de que no lo obvio:

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

La parte head::tail hay tan no coincide en la lista vacía

5

simplemente:

case head +: _ :+ last => 

por ejemplo:

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

Esto realmente no funciona en listas con un elemento. Para eso tendrías que agregar un caso adicional. –