Advertisement
Revolucent

Rust Grouping Constructs

Nov 24th, 2021
1,537
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 1.44 KB | None | 0 0
  1. /*
  2. Even BETTER grouping construct in Rust.
  3. */
  4.  
  5. pub struct GroupBy<A, B, I> {
  6.   iter: I,
  7.   test: Box<dyn Fn(&A) -> B>,
  8.   curr: Option<B>,
  9.   last: Option<A>
  10. }
  11.  
  12. impl<A, B, I> GroupBy<A, B, I> {
  13.   fn new<T: 'static>(iter: I, test: T) -> GroupBy<A, B, I> where T: Fn(&A) -> B {
  14.    GroupBy { iter, test: Box::new(test), curr: None, last: None }
  15.  }
  16. }
  17.  
  18. impl<A, B: Eq, I> Iterator for GroupBy<A, B, I>
  19.  where I: Iterator<Item=A>
  20. {
  21.  type Item = Vec<A>;
  22.  
  23.  fn next(&mut self) -> Option<Self::Item> {
  24.    let mut group = Vec::new();
  25.    if let Some(a) = self.last.take() {
  26.      group.push(a);
  27.    }
  28.    let test = &self.test;
  29.    loop {
  30.      match self.iter.next() {
  31.        None => break,
  32.        Some(a) => {
  33.          let new = Some(test(&a));
  34.          if self.curr == new || self.curr.is_none() {
  35.            group.push(a);
  36.            self.curr = new;
  37.          } else {
  38.            self.last = Some(a);
  39.            self.curr = new;
  40.            break;
  41.          }
  42.        }
  43.      }
  44.    }
  45.    if !group.is_empty() { Some(group) } else { None }
  46.  }
  47. }
  48.  
  49. pub trait IteratorExt: Iterator {
  50.  fn group_by<B: Eq, T: 'static>(self, test: T) -> GroupBy<Self::Item, B, Self>
  51.     where Self: Sized, T: Fn(&Self::Item) -> B
  52.   {
  53.     GroupBy::new(self, test)
  54.   }
  55.  
  56.   fn group(self) -> GroupBy<Self::Item, Self::Item, Self>
  57.     where Self: Sized, Self::Item: Eq + Clone
  58.   {
  59.     GroupBy::new(self, |a: &Self::Item| a.clone())
  60.   }
  61. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement