Use forall instead of filter on List[A]

797 views Asked by At

Am trying to determine whether or not to display an overtime game display flag in weekly game results report.

Database game results table has 3 columns (p4,p5,p6) that represent potential overtime game period score total ( for OT, Double OT, and Triple OT respectively). These columns are mapped to Option[Int] in application layer.

Currently I am filtering through game result teamA, teamB pairs, but really I just want to know if an OT game exists of any kind (vs. stepping through the collection).

def overtimeDisplay(a: GameResult, b: GameResult) = {
  val isOT = !(List(a,b).filter(_.p4.isDefined).filter(_.p5.isDefined).filter(_.p6.isDefined).isEmpty)
  if(isOT) {
    <b class="b red">
    {List( ((a.p4,a.p5,a.p6),(b.p4,b.p5,b.p6)) ).zipWithIndex.map{
      case( ((Some(_),None,None), (Some(_),None,None)), i)=> "OT"
      case( ((Some(_),Some(_),None), (Some(_),Some(_),None )), i)=> "Double OT"
      case( ((Some(_),Some(_),Some(_)), (Some(_),Some(_),Some(_) )), i)=> "Triple OT"
    }}
    </b>
  }
  else scala.xml.NodeSeq.Empty
}

Secondarily, the determination of which type of overtime to display, currently that busy pattern match (which, looking at it now, does not appear cover all the scoring scenarios), could probably be done in a more functional/concise manner.

Feel free to lay it down if you have the better way.

Thanks

2

There are 2 answers

6
Tomasz Nurkiewicz On BEST ANSWER

Not sure if I understand the initial code correctly, but here is an idea:

val results = List(a, b).map(r => Seq(r.p4, r.p5, r.p6).flatten)
val isOT = results.exists(_.nonEmpty)
val labels = IndexedSeq("", "Double ", "Triple ")
results.map(p => labels(p.size - 1) + "OT")

Turning score column to flat list in first line is crucial here. You have GameResult(p4: Option[Int], p5: Option[Int], p6: Option[Int]) which you can map to Seq[Option[Int]]: r => Seq(r.p4, r.p5, r.p6) and later flatten to turn Some[Int] to Int and get rid of None. This will turn Some(42), None, None into Seq(42).

1
AudioBubble On

Looking at this:

val isOT = !(List(a,b).filter(_.p4.isDefined).filter(_.p5.isDefined).filter(_.p6.isDefined).isEmpty)

This can be rewritten using exists instead of filter. I would rewrite it as follows:

List(a, b).exists(x => x.p4.isDefined && x.p5.isDefined && x.p6.isDefined)

In addition to using exists, I am combining the three conditions you passed to the filters into a single anonymous function.

In addition, I don't know why you're using zipWithIndex when it doesn't seem as though you're using the index in the map function afterwards. It could be removed entirely.