I have a method implemented in imperative and functional (I did my best here) ways. The method iterates over ArrayBuffer[Creature], calculates distance to each creature and return the closest or None (if no creatures in the world except 'this').
Imperative:
private def closestEnemy: Option[Creature] = {
var closest: Option[Creature] = None
var distanceToClosest = Int.MaxValue
for(creature <- game.creatures if creature != this) {
val distance = distanceTo(creature)
if(distance < distanceToClosest) {
closest = Some(creature)
distanceToClosest = distance
}
}
closest
}
Functional:
private def closestEnemy: Option[Creature] =
game.creatures filter { _ != this } map { creature => (creature, distanceTo(creature)) } match {
case creaturesWithDistance if creaturesWithDistance.isEmpty => None
case creaturesWithDistance => Some(creaturesWithDistance minBy { _._2 } _1)
}
The functional code looks less obvious (probably it can be simplified but I don't see how) and I'm not sure if I am able to read it on fly in a month. My question is it a matter of habit or functional isn't good for this particular case? Did you have such doubts when started Scala? Did your functional skills greatly improved after some time and totaly beat the imperative approach? Please post your experience.
Thanks!
You can do this simpler by using collect:
game.creatures collect { case creature if creature != this => (creature, distanceTo(creature)) }
collect
takes a PartialFunction
and will only return values at which this function is defined, so creature == this
will not be returned.
And also you can replace
case creaturesWithDistance if creaturesWithDistance.isEmpty => None
with
case Seq() => None
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With