Skip to content

Instantly share code, notes, and snippets.

@romac
Forked from rust-play/playground.rs
Created July 13, 2022 10:33
Show Gist options
  • Save romac/b5883fbe743806c75afc074fd519bb20 to your computer and use it in GitHub Desktop.
Save romac/b5883fbe743806c75afc074fd519bb20 to your computer and use it in GitHub Desktop.
Collate a sequence of ordered elements
use std::ops::{Add, RangeInclusive};
struct Collate<Iter, Item> {
iter: Iter,
current: Option<RangeInclusive<Item>>,
}
impl<Iter, Item> Collate<Iter, Item> {
fn new(iter: Iter) -> Self {
Self {
iter,
current: None,
}
}
}
impl<Iter, Item> Iterator for Collate<Iter, Item>
where
Iter: Iterator<Item = Item>,
Item: PartialOrd + Add<u64, Output = Item> + Copy,
{
type Item = RangeInclusive<Item>;
fn next(&mut self) -> Option<Self::Item> {
while let Some(item) = self.iter.next() {
if let Some(current) = self.current.take() {
if item == *current.end() {
self.current = Some(current);
} else if item == *current.end() + 1 {
self.current = Some(*current.start()..=item);
} else {
self.current = Some(item..=item);
return Some(current);
}
} else {
self.current = Some(item..=item);
}
}
self.current.take()
}
}
fn collate<Iter, Item>(iter: Iter) -> Collate<Iter, Item>
where
Iter: Iterator<Item = Item>,
Item: PartialOrd,
{
Collate::new(iter)
}
fn main() {
let items = vec![
1, 2, 3, 10, 10, 10, 11, 11, 20, 30, 31, 31, 32, 33, 35, 40, 40, 40, 40,
];
dbg!(&items);
let collated = collate(items.into_iter()).collect::<Vec<_>>();
dbg!(&collated);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment