Reputation: 8139
I'm trying to get more familiar with functional programming and I was wondering if there is a more elegant way to group a list into pairs of 2 and apply a function to those pairs.
case class Line(start: Vector, end: Vector) {
def isLeftOf(v: Vector) = (end - start).cross(v - start) < 0
}
case class Polygon(vertices: List[Vector]) {
def edges = (vertices.sliding(2).toList :+ List(vertices.last,vertices.head)).map(l => Line(l(0), l(1)))
def contains(v: Vector) = {
edges.map(_.isLeftOf(v)).forall(_ == true)
}
}
I'm talking about this line
def edges = (vertices.sliding(2).toList :+ List(vertices.last,vertices.head)).map(l => Line(l(0), l(1)))
Is there a better way to write this?
Upvotes: 1
Views: 841
Reputation: 51109
val edges = (vertices, vertices.tail :+ vertices.head).zipped map Line
See also these questions:
How do you turn a Scala list into pairs?
Most concise way to combine sequence elements
Upvotes: 2
Reputation: 52701
Well you can simplify a bit by doing this:
case class Polygon(vertices: List[Vector]) {
def edges = Line(vertices.last, vertices.head) :: vertices.sliding(2).map(l => Line(l(0), l(1))).toList
def contains(v: Vector) = edges.forall(_.isLeftOf(v))
}
I've done three things:
map
toList
to after map
so that you map over an Iterator, saving you from constructing two Lists.contains
to simply call forall
with the predicate.Upvotes: 0