2016-01-04 15 views
8

Sono utilizzo case x :: Nil => ... tentativo di assicurarsi che la lista è vuota, ma semplicemente abbino singolo elemento list.How posso usare pattern match ottenere una lista non vuota?come usare la corrispondenza del modello ottenere una lista non vuota in scala?

AGGIORNATO
Mi dispiace, sembra perdo qualcosa, c'è una scena speciale usare il match interno,

object AccountResult{ 
    def unapply(account: AccountResult): Option[(String, List[String])] = ??? 
} 

//ignore accountResult define please 
accountResult match { 
    case AccountResult(_, x :: _) => ... 
} 

come posso corrispondere accountResult che List [String] (x: : _) il valore non è Nil? e quindi ottenere l'elenco abbinato valore [String]

risposta

11

Invece di specificare solo la lista vuota con Nil, specificare qualcosa che può essere qualsiasi lista, ad es .:

case x :: tail => ... // tail is a local variable just like x, holding the tail of the list 

o semplicemente:

case x :: _ => ... 

se non si cura di o non si intende utilizzare la coda.

Questi modelli corrisponderà qualsiasi elenco con almeno un elemento (piuttosto che esattamente un elemento secondo il vostro modello attuale). Analogamente, il modello:

case x :: y :: the_rest => ... 

corrisponderà qualsiasi elenco con almeno due elementi.

Modifica (risposta al tuo commento):

È possibile assegnare ad una variabile all'interno di un modello caso, l'utilizzo di "@".Così, per (un uso tipico) di esempio che si può avere visto già:

case [email protected](_, x :: tail) => ... // do something with 'acc' 

o, abbinando l'uso si sta cercando per il tuo commento:

case AccountResult(_, [email protected](x :: tail)) => ... // do something with 'phone' 
+0

sembra grande, grazie! inoltre, se ho abbinato qualcosa, e ho bisogno di corrispondere al tipo interno, come ad esempio, 'AccountResult {def unpply (name: String, phone: List [String]) = ??? } qualcosa corrisponde {caso AccountResult (_, x :: tail) => ...} 'come posso ottenere le informazioni sul telefono, usare 'val phone = x :: tail' non è un'eleganza scelta – LoranceChen

+0

@LoranceChen ho modificato la mia risposta per includere un modo di gestire l'incarico all'interno di un pattern match per il tuo commento - anche se dovrei notare che l'etichetta generale è per te per aprire una nuova domanda. – Shadowlands

+0

L'ultimo è il mio bisogno, :-) grazie ancora @Shadowlands – LoranceChen

10

Per verificare se la lista non è vuota voi modello può corrispondere in questo modo:

list match { 
    case Nil => false 
    case _ => true 
} 

O

list match { 
    case Nil => false 
    case x::xs => true 
} 
+0

Nota che l'ordine è importante, altrimenti 'caso Nil' non sarà raggiungibile. – Maroun

2

Se questo è qualcosa che si usa spesso è possibile creare un matcher personalizzato come questo:

object NonEmpty { 
    def unapply(l: List[_]) = l.headOption.map(_ => l) 
} 

Questo può essere utilizzato in questo modo:

scala> List() match { case NonEmpty(l) => println(l) } 
scala.MatchError: List() (of class scala.collection.immutable.Nil$) 
    ... 33 elided 

scala> List(43) match { case NonEmpty(l) => println(l) } 
List(43) 

scala> List(43, 32) match { case NonEmpty(l) => println(l) } 
List(43, 32) 
+0

È un modo di libertà, ma non posso usare un oggetto specifico per unificare lo stile – LoranceChen

1

Se si desidera solo per assegnare un intero non vuota elenco a un val, senza la testa e la coda divisione, è sufficiente aggiungere un caso corrispondente una lista vuota, e un altro di assegnare l'elenco in un nome di variabile in questo modo:

accountResult match { 
    case List() => ??? // empty case 
    case myAccountResult => ??? //myAccountResult will contain the whole non-empty list 
} 

Nil fa anche il lavoro, facendo corrispondere una lista vuota

accountResult match { 
    case Nil => ??? // empty case 
    case myAccountResult => ??? //myAccountResult will contain the whole non-empty list 
} 
Problemi correlati