deltanovember
deltanovember

Reputation: 44041

Is it possible in Scala to simplify the following if/else statement?

I'm trying to store the maximum price. There are some other business rules in there but the three nested if statements look very procedural and messy. I'm wondering if there is a nicer more functional way to express the following logic.

val sunsetTime1 = "14:00:00.000"
val maxPrices = new HashMap[String, Double]

if (trade.dateTime.before(time1)) {
  if (maxPrices.contains(sunsetTime1)) {
    if (maxPrices(sunsetTime1) < trade.price) {
      maxPrices.put(sunsetTime1, price)
    }
  }
  else {
    maxPrices.put(sunsetTime1, price)
  }

}

Upvotes: 5

Views: 673

Answers (3)

Chuck
Chuck

Reputation: 237010

I'm pretty inexperienced in Scala, but my functional programming instincts tell me something like this:

if (trade.dateTime.before(time1)) {
  maxPrices get(sunsetTime1) 
  filterNot ( _ < trade.price ) 
  orElse ( maxPrices.put(sunsetTime1, price) )
}

AFAIK, the only difference from the original version is that it returns the old value rather than an AnyVal if a higher price was already in the map.

(If any real Scalistas disagree with any of this, please do feel free to comment.)

Upvotes: 3

user unknown
user unknown

Reputation: 36229

The statement (the outer if, I ignore) is of the form:

if (a) 
  if (b) 
    c
else 
  c 

in a table of combinations, we can write it:

      a
   | t| f
  --------
  t| c| c
b --------
  f| -| c

If a is false (right column), we do c, independently from a. If a is true, we do a b-check, and c is only done if b is true.

We can write it as

if (! (a && !b)) c

or

if (!a || b) c

The last form is more concise, but more functional? Thanks to the corrections in the comment. When in doubt, use testcases, or take the longer form.

Upvotes: 7

Anthony Accioly
Anthony Accioly

Reputation: 22461

I'm not an Scala expert, and you should check that code, but I guess pattern matching and Options are more Idiomatic Scala.

if (trade.dateTime.before(time1)) {
  maxPrices.get(sunsetTime1) match {
    case Some(oldPrice) if oldPrice < trade.price => maxPrices.put(sunsetTime1, price)
    case None => maxPrices.put(sunsetTime1, price)
  }
}

Cheers.

Upvotes: 7

Related Questions