distr_combinators/
histogram.rs1use indexmap::IndexMap;
2
3#[derive(Debug)]
5pub struct Histogram<T: std::cmp::Eq + std::hash::Hash> {
6 pub lookup: IndexMap<T, usize>
7}
8impl <T: std::cmp::Eq + std::hash::Hash> FromIterator<T> for Histogram<T> {
9 fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self {
10 let mut lookup = IndexMap::new();
11 for t in iter {
12 *lookup.entry(t).or_insert(0) += 1;
13 }
14 lookup.sort_by(|_, v1, _, v2| v1.cmp(v2));
16 Histogram { lookup }
17 }
18}
19
20impl <T: std::cmp::Eq + std::hash::Hash> Histogram<T> {
21 pub fn from(iter: impl IntoIterator<Item=T>) -> Self {
22 Self::from_iter(iter)
23 }
24
25 pub fn iter(&self) -> impl Iterator<Item = (&T, usize)> {
27 self.lookup.iter().map(|(k, v)| (k, *v))
28 }
29}
30
31impl<'a, T: std::cmp::Eq + std::hash::Hash> IntoIterator for &'a Histogram<T> {
32 type Item = (&'a T, usize);
33 type IntoIter = std::iter::Map<indexmap::map::Iter<'a, T, usize>, fn((&'a T, &'a usize)) -> (&'a T, usize)>;
34
35 fn into_iter(self) -> Self::IntoIter {
36 self.lookup.iter().map(|(k, v)| (k, *v))
37 }
38}
39
40impl<T: std::cmp::Eq + std::hash::Hash> IntoIterator for Histogram<T> {
41 type Item = (T, usize);
42 type IntoIter = indexmap::map::IntoIter<T, usize>;
43
44 fn into_iter(self) -> Self::IntoIter {
45 self.lookup.into_iter()
46 }
47}