joesan
joesan

Reputation: 15385

Pattern match a List of case classes in Scala

Say I have a List of case classes that I want to pattern match and return true or false if there is a type. For example.,

case class TypeA(one: String, two: Int, three: String)

val list = List(TypeA, TypeA, TypeA)

I want to now match against the list of types and see if TypeA contains a certain value for one of its parameter (say the first parameter). What I have is the following:

def isAvailableInTypeA(list: List[TypeA], checkStr: String) = {
  !(list.dropWhile(_.one != checkStr).isEmpty))
}

Is there a better more readable suggestion for what I want to achieve?

Upvotes: 4

Views: 2063

Answers (4)

jasonoriordan
jasonoriordan

Reputation: 893

You can define a pattern matching function which cycles through the list and checks for the value you want eg. "MATCH!" If it exists in any of the elements of the list then return true, otherwise return false.

def myMatch(in: List[TypeA]): Boolean = in match {
   //found, return true
   case TypeA("MATCH!",_,_) :: rest => true
   // not found, recursive call with remainder of list
   case TypeA(_,_,_) :: rest => myMatch(rest)
   //end of list, return false
   case _ => false
}

Negative case (returns false)

myMatch(List(TypeA("NOMATCH!",3,"a"), TypeA("NOMATCH!",3,"b"), TypeA("NOMATCH!",3,"c")))

Positive case (returns true)

myMatch(List(TypeA("NOMATCH!",3,"a"), TypeA("MATCH!",3,"b"), TypeA("NOMATCH!",3,"c")))

Upvotes: 1

elm
elm

Reputation: 20415

In order to verify a condition and actually fetch the first value that holds it consider, for

val l = List(TypeA("a",1,"aa"), TypeA("b",2,"bb"), TypeA("c",3,"cc"))

the use of collectFirst, for instance like this,

l.collectFirst { case tA if tA.one == "b" => tA }
res: Some(TypeA(b,2,bb))

l.collectFirst { case tA if tA.one == "d" => tA }
res: None

where a None option means no element in the collection held the condition.

Upvotes: 1

Marth
Marth

Reputation: 24812

If you want to check whether the predicate holds for an element of the list, use .exists.

scala> val l = List(TypeA("a",2,"b"), TypeA("b",2,"b"))
l: List[TypeA] = List(TypeA(a,2,b), TypeA(b,2,b))

scala> l.exists(_.one == "a")
res0: Boolean = true

scala> l.exists(_.one == "c")
res1: Boolean = false

Upvotes: 8

Richard Close
Richard Close

Reputation: 1905

This version is a bit more concise:

def listContainsValue(list: List[TypeA], checkStr: String): Boolean = {
  list.exists(_.one == checkStr)
}

Upvotes: 2

Related Questions