more_itertools/grouping/
bucket.rs

1use std::{collections::HashMap, hash::Hash, rc::Rc};
2
3#[allow(dead_code)]
4pub struct BucketInner<T>
5where 
6T: Clone + PartialEq + Eq + Hash
7{
8    buf: Vec<Vec<T>>, 
9    key_func: fn(&Vec<T>) -> Vec<T>,
10    table: HashMap<Vec<T>, Vec<Vec<T>>>
11}
12
13pub struct Bucket<T>
14where 
15T: Clone + PartialEq + Eq + Hash {
16    inner: Rc<BucketInner<T>>
17}
18
19pub struct Cursor<T> 
20where
21T: Clone + PartialEq + Eq + Hash
22{
23    inner: Rc<BucketInner<T>>
24}
25
26impl<T> Cursor<T> 
27where
28T: Clone + PartialEq + Eq + Hash {
29    pub fn get(&self, key: &Vec<T>) -> Option<&Vec<Vec<T>>> {
30        return self.inner.table.get(key);
31    }
32}
33
34
35impl<T> Bucket<T> 
36where 
37T: Clone + PartialEq + Eq + Hash
38{
39    pub fn new(buf: Vec<Vec<T>>, key_func: fn(&Vec<T>)->Vec<T>) -> Self {
40        let mut inner = BucketInner {
41            buf: buf,
42            key_func: key_func,
43            table: HashMap::new()
44        };
45
46        for i in inner.buf.iter() {
47            let _value = i;
48            let _key = key_func(_value);
49            let v = inner.table.entry(_key).or_insert(vec![]);
50            v.push(_value.clone());
51        }
52
53        let ret = Bucket {
54            inner: Rc::new(inner)
55        };
56
57        return ret;
58    }
59
60    pub fn keys(&self) -> Vec<Vec<T>> {
61        let mut ret = Vec::new();
62        for k in self.inner.table.keys() {
63            ret.push(k.clone());
64        }
65        return ret;
66    } 
67
68    pub fn get_cursor(&self) -> Cursor<T> {
69        Cursor {
70            inner: Rc::clone(&self.inner)
71        }
72    }
73}
74
75pub fn bucket<T>(buf: Vec<Vec<T>>, key: fn(&Vec<T>)->Vec<T>) -> Bucket<T> 
76where 
77T: Clone + PartialEq + Eq + Hash
78{
79    return Bucket::new(buf, key);
80}
81
82
83#[cfg(test)]
84mod tests {
85    use crate::utils::join_char_vec_second_level;
86
87    use super::*;
88
89    #[test]
90    fn test1() {
91        let v = vec!["a1", "b1", "c1", "a2", "b2", "c2", "b3"];
92        let mut v2: Vec<Vec<char>> = Vec::new();
93        for a in v.iter() {
94            let char_vec: Vec<char> = a.chars().collect();
95            v2.push(char_vec);
96        }
97
98        println!("{:?}", v2);
99
100        let b = bucket(v2, 
101            |x| { vec![(*(x.get(0).unwrap()))] });
102
103        println!("{:?}", join_char_vec_second_level(&b.keys()));
104
105        let cursor = b.get_cursor();
106        let m = cursor.get(&vec!['a']).unwrap();
107        assert_eq!(vec!["a1", "a2"], join_char_vec_second_level(m));
108
109        let cursor = b.get_cursor();
110        let m = cursor.get(&vec!['b']).unwrap();
111        assert_eq!(vec!["b1", "b2", "b3"], join_char_vec_second_level(m));
112
113        let cursor = b.get_cursor();
114        let m = cursor.get(&vec!['c']).unwrap();
115        assert_eq!(vec!["c1", "c2"], join_char_vec_second_level(m));
116    }
117}