Trying to port following Java method to Scala. Ending up with a lot of nested Map and ugly return statement from "foreach". converted method looks ugly just like its OO counterpart in Java.
-
3I would start by breaking this big, complex function into a bunch of small single-operation functions. That should help you get a better idea of how to do the translation.dhg– dhg2014-04-17 02:23:02 +00:00Commented Apr 17, 2014 at 2:23
-
Easier if you post your ugly Scala.som-snytt– som-snytt2014-04-17 07:08:22 +00:00Commented Apr 17, 2014 at 7:08
Add a comment
|
1 Answer
Instead of looping through lanes to locate a value, you want to lanes find (_.number == 42).
Express the guards as filters and default values as getOrElse.
Sample:
scala> case class Lane(number: Int)
defined class Lane
scala> val lanes: Seq[Lane] = Nil
lanes: Seq[Lane] = List()
scala> Option(lanes) filter (_.nonEmpty) flatMap (_.find(_.number == 42))
res0: Option[Lane] = None
scala> Option(lanes) filter (_.nonEmpty) flatMap (_.find(_.number == 42)) map (_.number) getOrElse -1
res1: Int = -1
or
scala> for (x <- Option(lanes); y <- x.find(_.number == 42)) yield y.number
res3: Option[Int] = None
Then refactor predicates out to little functions to get x find goodNumber and so on.
More feedback:
Folding is laudable, but usually you want to use max or maxBy if that's what you're doing.
spots maxBy (_.name.toInt)
You could express your missing condition as part of a fold, but it's easier just to scan the list again:
if (spots exists (!_.model.equalsIgnoreCase(vehicle.model))) fail
You can optimize later if necessary.
2 Comments
user2066049
Thanks. I have updated question with what my revised Scala solution looks like along with open questions.
WeaponsGrade
for (x <- Option(lanes); y <- x.find(_.number == 42)) yield y.number could be simplified to for (x <- lanes if x.number == 42) yield x, unless you need the Option wrapper for non-matching values.