Advertisement
Revolucent

Rust grouping/counting stuff

Nov 19th, 2021
2,184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.19 KB | None | 0 0
  1. // Just some code the help learn Rust, traits, lifetimes, etc.
  2.  
  3. mod group {
  4.   use core::slice::Iter;
  5.   use std::collections::HashMap;
  6.   use std::hash::Hash;
  7.  
  8.   pub struct GroupByIter<'a, E: 'a, F: 'a, G: Eq + 'a> where F: Fn(&'a E) -> G {
  9.    iter: Iter<'a, E>,
  10.     test: Box<F>,
  11.     curr: Option<G>,
  12.     last: Option<&'a E>
  13.  }
  14.  
  15.  impl<'a, E: 'a, F: 'a, G: Eq + 'a> GroupByIter<'a, E, F, G> where F: Fn(&'a E) -> G {
  16.    fn new(slice: &'a [E], test: F) -> GroupByIter<'a, E, F, G> {
  17.      GroupByIter { iter: slice.iter(), test: Box::new(test), curr: None, last: None }
  18.    }
  19.  }
  20.  
  21.  pub trait GroupBy {
  22.    type Item;
  23.  
  24.    fn group_by<'a, F: 'a, G: Eq + 'a>(&'a self, test: F) -> GroupByIter<'a, Self::Item, F, G> where Self::Item: 'a, F: Fn(&'a Self::Item) -> G;
  25.   }
  26.  
  27.   impl<E> GroupBy for [E] {
  28.     type Item = E;
  29.  
  30.     fn group_by<'a, F: 'a, G: Eq + 'a>(&'a self, test: F) -> GroupByIter<'a, E, F, G> where E: 'a, F: Fn(&'a E) -> G {
  31.      GroupByIter::new(self, test)
  32.    }
  33.  }
  34.  
  35.  impl<'a, E: 'a, F: 'a, G: Eq + 'a> Iterator for GroupByIter<'a, E, F, G> where F: Fn(&'a E) -> G {
  36.    type Item = Vec<&'a E>;
  37.  
  38.     fn next(&mut self) -> Option<Self::Item> {
  39.       let mut group = Vec::new();
  40.       if let Some(e) = self.last {
  41.         group.push(e);
  42.         self.last = None;
  43.       };
  44.       let test = &self.test;
  45.       loop {
  46.         match self.iter.next() {
  47.           None => break,
  48.           Some(e) => {
  49.             let new = Some(test(e));
  50.             if self.curr == new || self.curr.is_none() {
  51.               group.push(e);
  52.               self.curr = new;
  53.             } else {
  54.               self.last = Some(e);
  55.               self.curr = new;
  56.               break;
  57.             }
  58.           }
  59.         }
  60.       };
  61.       if !group.is_empty() { Some(group) } else { None }
  62.     }
  63.   }
  64.  
  65.   pub trait Countable {
  66.     type Item: Eq + Hash;
  67.    
  68.     fn counts<'a>(&'a self) -> HashMap<&'a Self::Item, usize>;
  69.  }
  70.  
  71.  impl<E: Eq + Hash> Countable for [E] {
  72.    type Item = E;
  73.  
  74.    fn counts<'a>(&'a self) -> HashMap<&'a E, usize> {
  75.       let mut map = HashMap::new();
  76.       for e in self {
  77.         map.insert(e, map.get(e).unwrap_or(&0) + 1);
  78.       }
  79.       map
  80.     }
  81.   }
  82. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement