Skip to content

Commit b496584

Browse files
authored
add groupByOrdered (#346)
1 parent 88909f9 commit b496584

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

core/src/main/scala/flatgraph/traversal/Language.scala

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package flatgraph.traversal
33
import flatgraph.help.{Doc, Traversal}
44
import flatgraph.{Accessors, Edge, GNode, MultiPropertyKey, OptionalPropertyKey, PropertyKey, Schema, SinglePropertyKey}
55

6+
import java.util
67
import scala.annotation.implicitNotFound
78
import scala.collection.immutable.ArraySeq
89
import scala.collection.{Iterator, mutable}
@@ -57,7 +58,24 @@ class GenericSteps[A](iterator: Iterator[A]) extends AnyVal {
5758
counts.to(Map)
5859
}
5960

60-
def groupBy[K](f: A => K): Map[K, List[A]] = l.groupBy(f)
61+
/** Execute the traversal and group elements by a given transformation function, ignoring the iterator order. Use is discouraged. */
62+
@Doc(info =
63+
"Execute the traversal and group elements by a given transformation function, ignoring the iterator order. Use is discouraged, because iteration order is not reproducible, which tends to produce very bad bugs."
64+
)
65+
def groupBy[K](f: A => K): Map[K, List[A]] = l.groupBy(f)
66+
67+
/** Execute the traversal and group elements by a given transformation function, respecting the order of the iterator */
68+
@Doc(info = "Execute the traversal and group elements by a given transformation function, respecting the order of the iterator.")
69+
def groupByStable[K](f: A => K): scala.collection.SeqMap[K, scala.collection.Seq[A]] = {
70+
val res = mutable.LinkedHashMap[K, mutable.ArrayBuffer[A]]()
71+
while (iterator.hasNext) {
72+
val item = iterator.next
73+
val key = f(item)
74+
res.getOrElseUpdate(key, mutable.ArrayBuffer[A]()).addOne(item)
75+
}
76+
res
77+
}
78+
6179
def groupMap[K, B](key: A => K)(f: A => B): Map[K, List[B]] = l.groupMap(key)(f)
6280
def groupMapReduce[K, B](key: A => K)(f: A => B)(reduce: (B, B) => B): Map[K, B] = l.groupMapReduce(key)(f)(reduce)
6381

core/src/test/scala/flatgraph/traversal/IterableOnceExtensionTests.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,11 @@ class IterableOnceExtensionTests extends AnyWordSpec with Matchers {
4747
Seq(1, 2).loneElementOption shouldBe None
4848
}
4949

50+
"groupBy respects iteration order" in {
51+
Seq(5, 4, 3, 2, 1, 0).groupByStable(x => x % 3).valuesIterator.map { _.l }.l shouldBe List(List(5, 2), List(4, 1), List(3, 0))
52+
Seq(5, 4, 3, 2, 1, 0).groupByStable(x => (x + 1) % 3).valuesIterator.map { _.l }.l shouldBe List(List(5, 2), List(4, 1), List(3, 0))
53+
Seq(5, 4, 3, 2, 1, 0).groupByStable(x => (x + 2) % 3).valuesIterator.map { _.l }.l shouldBe List(List(5, 2), List(4, 1), List(3, 0))
54+
55+
}
56+
5057
}

0 commit comments

Comments
 (0)