J'utilise la méthode case x :: Nil => ...
afin de m'assurer que la liste est non vide, mais elle correspond simplement à la liste d'éléments uniques. Comment puis-je utiliser une correspondance de modèle pour obtenir une liste non vide?
MIS À JOUR
Je suis désolé, il semble que j'ai perdu quelque chose, il y a une scène spéciale utiliser le match interne,
object AccountResult{
def unapply(account: AccountResult): Option[(String, List[String])] = ???
}
//ignore accountResult define please
accountResult match {
case AccountResult(_, x :: _) => ...
}
comment puis-je faire correspondre la valeur de accountResult dont la valeur List [String] (x :: _) n'est pas Nil? et ensuite obtenir la valeur correspondante List [String]
Au lieu de spécifier uniquement la liste vide avec Nil
, spécifiez un élément pouvant être n'importe quelle liste, par exemple:
case x :: tail => ... // tail is a local variable just like x, holding the tail of the list
ou simplement:
case x :: _ => ...
si vous vous en fichez ou si vous n'utiliserez pas la queue.
Ces modèles correspondront à toute liste avec au moins un élément (plutôt que exactement un élément selon votre modèle existant). De même, le motif:
case x :: y :: the_rest => ...
correspondra à toute liste avec au moins deux éléments.
Edit (réponse à votre commentaire):
Vous pouvez affecter une variable dans un modèle de casse en utilisant "@
". Donc, pour un exemple (d'utilisation typique) que vous avez peut-être déjà vu:
case acc@AccountResult(_, x :: tail) => ... // do something with 'acc'
ou, correspondant à l'utilisation que vous recherchez par votre commentaire:
case AccountResult(_, phone@(x :: tail)) => ... // do something with 'phone'
Pour vérifier si la liste est non vide, vous pouvez associer un motif de cette façon:
list match {
case Nil => false
case _ => true
}
Ou
list match {
case Nil => false
case x::xs => true
}
Si c'est quelque chose que vous utilisez souvent, vous pouvez créer un matcher personnalisé comme ceci:
object NonEmpty {
def unapply(l: List[_]) = l.headOption.map(_ => l)
}
Cela peut être utilisé comme ceci:
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)
Si vous voulez simplement assigner une liste entière non vide à un val, sans scinder tête et queue, vous ajoutez simplement un cas correspondant à une liste vide et un autre assignant la liste à un nom de variable comme celui-ci:
accountResult match {
case List() => ??? // empty case
case myAccountResult => ??? //myAccountResult will contain the whole non-empty list
}
Nil
fait aussi le travail, en faisant correspondre une liste vide
accountResult match {
case Nil => ??? // empty case
case myAccountResult => ??? //myAccountResult will contain the whole non-empty list
}