My implementation works, but it looks very ugly. Curious to see how it's better implemented.
The zipWith
function takes a list of lists (List[List[A]]
), or a row with columns if you like. It will then transform this into a column with rows and applies a function List[A]=>B
to obtain a List[B]
. Hopefully the unit test below explains this better.
test("zipWith"){
val input = List(List(1,2,3), List(4,5,6), List(7,8,9))
val expected = List("1::4::7", "2::5::8", "3::6::9")
assert(zipWith(input)(_.mkString("::")) === expected)
}
and the implementation is:
def zipWith[A, B](lists: List[List[A]])(f: List[A] => B): List[B] = {
@tailrec
def loop(acc: List[B], input: List[List[A]]): List[B] = {
val init = (Nil: List[List[A]], Nil: List[A])
val (left, zipped) = input.foldLeft(init)((z, a) => {
val (tails, heads) = z
(a.tail :: tails, a.head :: heads)
})
if (left.foldLeft(false)(_ || _.isEmpty))
f(zipped.reverse) :: acc
else
loop(f(zipped.reverse) :: acc, left.reverse)
}
loop(Nil, lists).reverse
}
def zipWith[A, B](lists: List[List[A]])(f: List[A] => B): List[B] = lists.map(f)
? Are you looking at improving your style? \$\endgroup\$