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}
Это создает две последовательности из первой, где первый и второй члены кортежей ненулевые соответственно.
Однако для этого требуются две итерации исходной последовательности, что весьма неэффективно.
Любое предложение по достижению этого с помощью одной итерации (+ любое другое улучшение) - при условии, что сама последовательность будет нетривиальной.





Просто используйте изменяемые ListBuffer. Пока они не выходят за рамки вашей вспомогательной функции, нет ничего плохого в использовании быстро изменяемых буферов и старых добрых for-циклов и if-else.
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)
}
Использование:
unzipAndFilter(List((8,0),(3,4),(0,9),(6,1)))(_ > 0)(_ > 0)
// (List(8, 3, 6),List(4, 9, 1))
Или с синтаксисом расширения Scala 3:
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)
}
а потом
input.unzipAndFilter(_ > 0)(_ > 0)
К сожалению, в стандартной библиотеке unzipCollect, похоже, нет.
Посмотрите
partitionMapВы также можете сделать самиfoldLeft