Some Scala-related thoughts on this Python function:
def GetContourPoints(self, array):
"""Parses an array of xyz points and returns a array of point dictionaries."""
return zip(*[iter(array)]*3)
The most straightforward approach would be to use Iterable.grouped
:
(1 to 8).grouped(3).map(_.toList).flatMap({
case a::b::c::Nil => Some((a,b,c))
case _ => None
}).toList
// List((1,2,3), (4,5,6))
To avoid creating the intermediary collections and only involve tuples, we could try using Iterable.zip
:
def groupBy3[A](it: Iterator[A]): Iterator[(A,A,A)] =
((it zip it) zip it).map({ case ((a, b), c) => (a,b,c) })
groupBy3((1 to 6).iterator).toList
// List((1,2,3), (4,5,6))
But this fails:
groupBy3((1 to 8).iterator).toList
// java.util.NoSuchElementException: next on empty iterator
// at scala.collection.Iterator$$anon$2.next(Iterator.scala)
The operation could be implemented more directly without abusing Iterable.zip
:
def groupBy3[A](it: Iterable[A]): Iterator[(A, A, A)] = new Iterator[(A, A, A)] {
var s = it.toStream
def hasNext = s.take(3).size == 3
def next = { val t = (s(0), s(1), s(2)); s = s drop 3; t }
}
groupBy3(1 to 8).toList
// List((1,2,3), (4,5,6))
Frustratingly, Tuple3Zipped.Ops.zipped
(provided implicitly by Predef.tuple3ToZippedOps
) seems to provide something close to useful here, but the context bound requires that the tuple's types be IterableLike
, and Iterator
does not qualify.
I think this all just reiterates that tuples are tough to use elegantly in static type systems without dependent types (hence Tuple1
, Tuple2
, Tuple3
, Tuple4
, Tuple5
, …).
Of course, the benefit of tuples over a Scala collection is static typing, which exists nowhere in Python. So a more apt comparison would simply be
(1 to 8).grouped(3).filter(_.size == 3).toList
// List(Vector(1, 2, 3), Vector(4, 5, 6))