/* Even BETTER grouping construct in Rust. */ pub struct GroupBy { iter: I, test: Box B>, curr: Option, last: Option } impl GroupBy { fn new(iter: I, test: T) -> GroupBy where T: Fn(&A) -> B { GroupBy { iter, test: Box::new(test), curr: None, last: None } } } impl Iterator for GroupBy where I: Iterator { type Item = Vec; fn next(&mut self) -> Option { let mut group = Vec::new(); if let Some(a) = self.last.take() { group.push(a); } let test = &self.test; loop { match self.iter.next() { None => break, Some(a) => { let new = Some(test(&a)); if self.curr == new || self.curr.is_none() { group.push(a); self.curr = new; } else { self.last = Some(a); self.curr = new; break; } } } } if !group.is_empty() { Some(group) } else { None } } } pub trait IteratorExt: Iterator { fn group_by(self, test: T) -> GroupBy where Self: Sized, T: Fn(&Self::Item) -> B { GroupBy::new(self, test) } fn group(self) -> GroupBy where Self: Sized, Self::Item: Eq + Clone { GroupBy::new(self, |a: &Self::Item| a.clone()) } }