V P
V P

Reputation: 15

Scala: Best Way to Avoid Multiple time doing same operation in different Match-case

I want to find the minimum of all the values in a row of a table (there might be null values, the columns might be of different types-Int, Long, Double, Boolean).

The return type of the function depends on the input columns, if all are Int then the return type should be Int. If mix of different types, then double, etc.

I have the knowledge of what the returnType would be.

Method is like:

 def findMin(args: List[Any]): Any =

One possible solution could be:

returnType match {
  case IntType =>
     minValInt = Int.Min
     for(args){
        check for not null 
        for(arg <- args) {
          temp: Int  = arg match {
             case x: Int => x
             case x: Boolean => convert to Int              
          }
        minValInt = min(minValInt, temp)
        return minValInt

  case LongType =>
     minValLong = Long.Min
     for(args){
       check for not null -> minValLong = min(minValLong, arg) (some restrictions while using the arg value directly)
     }
     return minValLong

  case DoubleType =>
     minValDouble = Double.Min
     for(arg <- args){
       check for not null 
       temp: Double = arg match {
          case x: Int => convert to double 
          case x: Long => convert to double (some restrictions while converting)
          case x: Double => x
          case x: Boolean => convert to double
       }
       minValDouble = min(minValDouble, temp)
     }
     return minValDouble
}

Can this be done in single match-case or something better "more neatly"?

Upvotes: 0

Views: 116

Answers (2)

Det
Det

Reputation: 435

Beside my lack of imagination regarding the use case, you already defined the function type to be List [Any] -> Any in your question.

So you are telling the compiler effectively nothing about what to expect and lose the advantage of having a static type system.

Please note that functional programming with static types is about defining the input domain and map it to the output domain at compile time. So a function returning an Int is not identical to a function returning a Long or one returning a Double. So either they are different functions or you define the output domain to be of the common super type of all possible return types, losing specific information on the way.

Regarding the shown code it seems that the return type is any of Int, Long, Double depending on the maximum precision needed to return the min value.

As an Int fits in a Long and both fit in a Double, why not declare Double as the guaranteed maximum precision return type?

Thus the function would be of type List[Any] -> Double, making the rest of the program specific at compile time an thus type safe?

Upvotes: 0

Dima
Dima

Reputation: 40510

Something like this perhaps?

list.flatMap(x => Option(x)).minBy { 
   case n: Number => n.doubleValue
   case true => 1.0
   case false => 0.0
}(Ordering.Double)

Upvotes: 1

Related Questions