-1

I am new to Scala and I am trying to execute = following code in Scala:

scala> case class FoldExp(firstname : String, lname : String, age : Int, sex : String)

defined class FoldExp

scala> object Foo{
 | def apply(firstname : String, lname : String, age : Int, sex : String) = new FoldExp(firstname,lname,age,sex)
 | }

defined object Foo

scala> val foldList = List(Foo("Hugh", "Jass", 25, "male"),Foo("Biggus"," Dickus", 43, "male"),Foo("Incontinentia", "Buttocks", 37, "female"))

foldList: List[FoldExp] = List(FoldExp(Hugh,Jass,25,male), FoldExp(Biggus, Dickus,43,male), FoldExp(Incontinentia,Buttocks,37,female))

val secTry = foldList.foldLeft(List[String]()){(w,f) =>
       val comment = f.age match{
       case (f.age == 25) => "Band A"
       case (f.age > 30) => "Band B"
       case (f.age > 50) => "Band D"
       }
       w:+ s"${f.firstname},${f.age} $comment"

  }

The above block of code threw following error:

<console>:11: error: not found: value foldList
   val secTry = foldList.foldLeft(List[String]()){(w,f) =>
                ^
<console>:13: error: not found: value ==
              case (f.age == 25) => "Band A"
                          ^
<console>:14: error: not found: value >
              case (f.age > 30) => "Band B"
                          ^
<console>:15: error: not found: value >
              case (f.age > 50) => "Band D"

I want to categorize people in the list into their respective bands based on their age. But iam not able to achieve this using pattern matching. Could anyone tell me why the above approach is wrong and what is the method to be followed to achieve my objective. Any attempt to find solution to the above problem is appreciated. Thanks in advance.

Anon
  • 320
  • 2
  • 14

2 Answers2

2

You can't put expressions in case clauses directly. Something like this should work:

 val comment = f.age match {
     case 25 => "Band A"
     case a if a > 50 => "Band D"
     case a if a > 30 => "Band B"

 }

Note, that I swapped around the >30 and >50 cases, because match statements are evaluated in order, and evaluation is stopped as soon as the first match found. So, if a > 30 comes before a>50, then the latter will never end up being executed, because everything that matches it, would match the previous one as well.

Also note, that this will throw a MatchError if age is less than 25 or if it is between 26 and 29. To avoid that, you need a default "catch all" case at the end, something like case _ => "Unknown band"

Dima
  • 39,570
  • 6
  • 44
  • 70
0

Your pattern matching is not right, you are putting conditions as cases, instead of a value and then, the condition. The power of case classes is (among many others) that you can pattern match against them with an easy-to-read syntax:

I made some tests and is working fine to me as follows (Check the default case)

 val foldList = List(Foo("William", "Shakespeare", 40, "M"), Foo("Rudyard", "Kipling", 25, "M"))

  val secTry = foldList.foldLeft(List[String]()){(w,f) =>
    val comment = f match{
      case FoldExp(_, _, a, _) if a == 25 => "Band A"
      case FoldExp(_, _, a, _) if a > 50 => "Band D"
      case FoldExp(_, _, a, _) if a > 30 => "Band B"
      case _ => "Band Default"

    }
    w:+ s"${f.firstname},${f.age} $comment"
SCouto
  • 7,808
  • 5
  • 32
  • 49
  • Nothing will go into Band D, because any value > 30 will go into Band B (case statements are evaluated in order). Also, there's no default case. Ages of 25 go into Band A, anything greater than 30 into Band B, and any other value (20, 21, 22, 23, 24, 26, 27, 28, 29, 30, etc.) will have no matching band and will result in a `MatchError` exception. Also, why match on the whole case class when you're just looking at age? – Mike Allen Nov 07 '17 at 14:17
  • You're right about band d. I've edited my answer to fix that. About default case, i've just translate the question's logic. – SCouto Nov 07 '17 at 14:20