Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use pattern match get a nonEmpty list in scala?

I'm use case x :: Nil => ... attempt to make sure the list is nonEmpty, but it just match single element list.How can I use pattern match get a nonEmpty list?

UPDATED
I'm sorry,it seems I lose something, there is a special scene use the match inner,

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

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

how can I match accountResult which List[String] (x :: _) value is not Nil? and then get the matched List[String] value

like image 341
LoranceChen Avatar asked Jan 04 '16 05:01

LoranceChen


People also ask

How do you match a pattern in Scala?

A pattern match includes a sequence of alternatives, each starting with the keyword case. Each alternative includes a pattern and one or more expressions, which will be evaluated if the pattern matches. An arrow symbol => separates the pattern from the expressions.

What is the use of Scala pattern matching?

Pattern matching is a way of checking the given sequence of tokens for the presence of the specific pattern. It is the most widely used feature in Scala. It is a technique for checking a value against a pattern. It is similar to the switch statement of Java and C.

Does Scala have pattern matching?

Notes. Scala's pattern matching statement is most useful for matching on algebraic types expressed via case classes. Scala also allows the definition of patterns independently of case classes, using unapply methods in extractor objects.

How is case class used in pattern matching?

Case classes help us use the power of inheritance to perform pattern matching. The case classes extend a common abstract class. The match expression then evaluates a reference of the abstract class against each pattern expressed by each case class.


3 Answers

Instead of specifying only the empty list with Nil, specify something that can be any list, eg.:

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

or simply:

case x :: _ => ...

if you don't care about or won't be using the tail.

These patterns will match any list with at least one element (rather than exactly one element as per your existing pattern). Similarly, the pattern:

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

will match any list with at least two elements.

Edit (response to your comment):

You can assign to a variable within a case pattern, using "@". So, for (a typical usage) example that you may have seen already:

case acc@AccountResult(_, x :: tail) => ... // do something with 'acc'

or, matching the usage you are seeking per your comment:

case AccountResult(_, phone@(x :: tail)) => ... // do something with 'phone'
like image 76
Shadowlands Avatar answered Oct 04 '22 18:10

Shadowlands


To check if list is non empty you can pattern match this way:

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

Or

list match {
  case Nil => false
  case x::xs => true  
}
like image 24
Nyavro Avatar answered Oct 04 '22 16:10

Nyavro


If you just want to assign a whole non-empty list to a val, without splitting head and tail, you just add a case matching an empty list, and another one assigning the list to a variable name like this:

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

Nil does the job as well, matching an empty list

accountResult match {
  case Nil => ??? // empty case
  case myAccountResult => ??? //myAccountResult will contain the whole non-empty list  
}
like image 8
Visiedo Avatar answered Oct 04 '22 16:10

Visiedo