Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching lists of certain size or greater/less

Tags:

Is there a way to specify a pattern that matches a List with a size greater (or less) or equal a certain value in Scala?

For example, if I want to apply the same action to all lists of size 3 or less:

list match {
    case Nil => op(list) 
    case x :: Nil => op(list)
    case x :: y :: Nil => op(list)
    case x :: y :: z :: Nil => op(list)
    case x :: tail => other(list)
} 

Is there a way to reduce this to two cases?

like image 409
Dan Avatar asked Apr 17 '13 02:04

Dan


People also ask

What is pattern matching explain?

In computer science, pattern matching is the act of checking a given sequence of tokens for the presence of the constituents of some pattern.

What is 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.

Which method of case class allows using objects in pattern matching?

Case classes are Scala's way to allow pattern matching on objects without requiring a large amount of boilerplate. In the common case, all you need to do is add a single case keyword to each class that you want to be pattern matchable.

What is pattern matching syntax?

Pattern matching is a technique where you test an expression to determine if it has certain characteristics. C# pattern matching provides more concise syntax for testing expressions and taking action when an expression matches.


4 Answers

Yes, although you'll need to reverse the order of the cases:

list match {
  case l @ (_ :: _ :: _ :: _) => other(l)
  case l => op(l)
}

Note that I've bound a new variable l to the list in the pattern instead of referring to list, and that I've used _ when I don't need a variable. I'd suggest sticking to both of these practices, but the answer would work exactly the same without them.

like image 191
Travis Brown Avatar answered Oct 20 '22 01:10

Travis Brown


If you insist on using a pattern match (maybe you want to include more match cases?), you can use a guard condition for it:

list match {
    case l if(l.size <= 3) => op(l)
    case l => other(l)
}
like image 33
Fynn Avatar answered Oct 20 '22 00:10

Fynn


What's wrong with a plain old if / else??

if (list.length >= minimumLength)
  longer(list)
else
  shorter(list)
like image 20
Randall Schulz Avatar answered Oct 20 '22 00:10

Randall Schulz


You can also do it with:

list.splitAt(len) match {
   case (xs, Nil) => other(xs)
   case (_, _) => op(list)
}

Also the complexity is O(len) thus even if list if long, len is deciding factor.

The above calls op if list.size < len else calls other

like image 42
Jatin Avatar answered Oct 19 '22 23:10

Jatin