Created with <3 with dartpad.dev.
Last active
March 14, 2023 21:01
-
-
Save plammens/a2e6882a352a12e681a4a23e7d9f1a69 to your computer and use it in GitHub Desktop.
groupConsecutiveBy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension MoreIterableTools<E> on Iterable<E> { | |
/// Group consecutive elements with the same key. | |
Iterable<MapEntry<K, Iterator<E>>> groupConsecutiveBy<K>( | |
K Function(E) keyOf, | |
) sync* { | |
final iterator = this.iterator; | |
bool moveNext = iterator.moveNext(), lastGroupConsumed = true; | |
while (moveNext) { | |
if (!lastGroupConsumed) { | |
throw StateError("Can't advance to the next group" | |
" until the previous group has been fully consumed."); | |
} | |
final currentKey = keyOf(iterator.current); | |
lastGroupConsumed = false; | |
Iterable<E> makeGroup() sync* { | |
do { | |
yield iterator.current; | |
} while ((moveNext = iterator.moveNext()) && | |
keyOf(iterator.current) == currentKey); | |
lastGroupConsumed = true; | |
} | |
yield MapEntry(currentKey, makeGroup().iterator); | |
} | |
} | |
} | |
List<E> consume<E>(Iterator<E> iterator) { | |
final result = <E>[]; | |
while (iterator.moveNext()) { | |
result.add(iterator.current); | |
} | |
return result; | |
} | |
Iterable<E> generateInfinitely<E>(E Function(int) generator) sync* { | |
for (int i = 0; true; ++i) { | |
yield generator(i); | |
} | |
} | |
void main() { | |
final iterable = generateInfinitely((i) => i); | |
final groupBy = iterable.groupConsecutiveBy((i) => i ~/ 10).iterator; | |
groupBy.moveNext(); | |
final group1 = groupBy.current; | |
final group1Elements = group1.value; | |
group1Elements.moveNext(); | |
print(group1Elements.current); | |
print(consume(group1Elements)); | |
groupBy.moveNext(); | |
final group2 = groupBy.current; | |
final group2Elements = group2.value; | |
group2Elements.moveNext(); | |
print(consume(group2Elements)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment