val subjectpairs = IndexedSeq((8,0),(3,4),(0,9),(6,1))
val priors = subjectpairs.map { case( f,_) => f}.filter{ _ >0.0}
val posts = subjectpairs.map { case( _,l) => l}.filter{ _ >0.0}
This creates 2 sequences from the first , with the first and second members of tuples as non-zero respectively.
However , this needs 2 iterations of the source sequence - which is quite inefficient.
Any suggestion on achieving this with a single iteration ( + any other improvement) - given that the sequence itself will be non-trivial.
Just use mutable ListBuffer
s. As long as they don't escape the scope of your helper function, there is nothing wrong with using fast mutable buffers and good ol' for
-loops and if
-else
s.
import scala.collection.mutable.ListBuffer
def unzipAndFilter[A, B](input: List[(A, B)])(pA: A => Boolean)(pB: B => Boolean): (List[A], List[B]) = {
val aBldr = new ListBuffer[A]
val bBldr = new ListBuffer[B]
for (a, b) <- input do
if (pA(a)) aBldr += a
if (pB(b)) bBldr += b
(aBldr.result, bBldr.result)
}
Usage:
unzipAndFilter(List((8,0),(3,4),(0,9),(6,1)))(_ > 0)(_ > 0)
// (List(8, 3, 6),List(4, 9, 1))
Or with Scala 3 extension syntax:
extension [A, B](input: List[(A, B)])
def unzipAndFilter[A, B](pA: A => Boolean)(pB: B => Boolean): (List[A], List[B]) = {
val aBldr = new ListBuffer[A]
val bBldr = new ListBuffer[B]
for (a, b) <- input do
if (pA(a)) aBldr += a
if (pB(b)) bBldr += b
(aBldr.result, bBldr.result)
}
and then
input.unzipAndFilter(_ > 0)(_ > 0)
There seems to be no unzipCollect
in the standard library, unfortunately.