0

I have written code to calculate some condition in old style. But is there any other way to write code using more functional programming.

def getAgeType(age: Int) = 
   age match {
  case age:Int if (age <= 10) => println("This age belongs to kids")
  case age:Int if (age > 10 && age <= 20) => println("This age belongs to teens")
  case age:Int if (age > 20 && age <= 60) => println("This age belongs to adults")
  case age:Int if (age > 60) => println("This age belongs to adults")
}

Can someone give me better code. Thanks in advance kanti

kanti
  • 15
  • 4
  • 4
    This belongs in the code review, not stack overflow – sinanspd Oct 08 '19 at 04:13
  • 3
    The `: Int` is unnecessary. And in this case I would go with `if / else` instead of `match`. Finally, I would make the method return a **String**, or my own datatype describing age range instead of printing. - Apart from that, the code is totally okey. – Luis Miguel Mejía Suárez Oct 08 '19 at 04:15
  • I am just beginner.Here people will have more knowledge than me. I just wnat to check any better ideas rather than my code. Thanks for your suggestions @Luis Miguel – kanti Oct 08 '19 at 04:28

4 Answers4

3

If conditions get to complicated, you can use custom unapply pattern to make it readable

// ========== Custom unapply pattern ==========
  def getAgeType(age: Int): Unit =
    age match {
      case Kid(_)   => println("This age belongs to kids")
      case Teen(_)  => println("This age belongs to teens")
      case Adult(_) => println("This age belongs to adults")
    }

  object Kid {
    def unapply(age: Int): Option[Int] = if (age <= 10) Some(age) else None
  }
  object Teen {
    def unapply(age: Int): Option[Int] = if (age > 10 && age <= 20) Some(age) else None
  }
  object Adult {
    def unapply(age: Int): Option[Int] = if (age > 10) Some(age) else None
  }

  // ========== Another way ==========
  def isKid(age: Int)   = age <= 10
  def isTeen(age: Int)  = age > 10 && age <= 20
  def isAdult(age: Int) = age > 20

  def getAgeType1(age: Int): Unit =
    age match {
      case _ if isKid(age)   => println("This age belongs to kids")
      case _ if isTeen(age)  => println("This age belongs to teens")
      case _ if isAdult(age) => println("This age belongs to adults")
    }
Pritam Kadam
  • 2,388
  • 8
  • 16
1

Avoid this pattern:

age match { case age . . .

The case age code creates a new variable with the same name as the match variable, thus shadowing the former and making it unavailable in the case clause. In your example that wouldn't make much difference, but it's unnecessary and makes the code look amateurish. It's also a bad habit that can lead to real confusion when seen in real code.

The better alternative is to create a new variable indicating its usage/meaning.

age match {
  case child if child <= 10 => . . .
  case old   if old > 60    => . . .

Or, better yet, if you don't really need a new variable.

age match {
  case _ if age <= 10 => . . .
  case _ if age > 60  => . . .

Which makes it just that much clearer that using match isn't a good "match" for this particular code.

jwvh
  • 50,871
  • 7
  • 38
  • 64
1

You should avoid using pattern matching if you're not actually checking against a pattern. In your case, you can really simplify everything using simple conditions:

val category = if (age <= 10) "kids" else if (age <= 20) "teens" else "adults"
println(s"This age belongs to $category")

People often forget that in Scala if/else expressions are actually expressions: they have a value, in this case of type String. This is like a more powerful variant of ternary conditions in other languages.

In my opinion, this is much simpler and concise than using pattern matching. It is also likely to be more efficient, because the Scala compiler often fails to compile simple pattern matches to efficient conditions in bytecode.

francoisr
  • 4,407
  • 1
  • 28
  • 48
0

How about this? Above answers gave you great suggestions, but I want to suggest small change to your code just for readability. see also similar question

//ensure that age is not negative
def getAgeType(age: Int) = 
   age match {
      case _ if 0 to 10 contains age => println("This age belongs to kids")
      case _ if 11 to 20 contains age => println("This age belongs to teens")
      case _ if 21 to 60 contains age => println("This age belongs to adults")
      case _ => println("This age belongs to adults")
}

osehyum
  • 145
  • 1
  • 6