-
Notifications
You must be signed in to change notification settings - Fork 1
/
EitherIterator.scala
77 lines (66 loc) · 1.9 KB
/
EitherIterator.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package org.hammerlab.iterator
import org.hammerlab.iterator.bulk.BufferedBulkIterator._
import scala.collection.mutable.ArrayBuffer
case class EitherIterator[T, U](it: BufferedIterator[Either[T, U]]) {
def findLeft: Option[T] =
it
.collect {
case Left(t) ⇒ t
}
.buffered
.headOption
def groupByLeft: BufferedIterator[(T, Iterator[U])] = {
// Clear out any leading Rights
it
.collectwhile {
case Right(_) ⇒ null
}
.toList
new SimpleBufferedIterator[(T, BufferedIterator[U])] {
var curLeft: Option[T] = None
var curRights = Iterator[U]().buffered
override protected def _advance: Option[(T, BufferedIterator[U])] = {
// Clear any unused elements from the previous rights/U's/"values" iterator
curRights.toList
it
.nextOption
.collect {
case Left(t) ⇒
curRights =
it
.collectwhile {
case Right(u) ⇒ u
}
t → curRights
case Right(u) ⇒
throw new IllegalStateException(
s"nextOption should not be a Right"
)
}
}
}
}
def roundUpRight: BufferedIterator[(Seq[T], U)] =
new SimpleBufferedIterator[(Seq[T], U)] {
override protected def _advance: Option[(Seq[T], U)] = {
val lefts = ArrayBuffer[T]()
while (true) {
it.headOption match {
case Some(Left(t)) ⇒
it.next
lefts += t
case Some(Right(u)) ⇒
it.next
return Some(lefts → u)
case None ⇒
return None
}
}
???
}
}
}
object EitherIterator {
implicit def makeEitherIterator[T, U](it: Iterator[Either[T, U]]): EitherIterator[T, U] =
EitherIterator(it.buffered)
}