more_itertools/grouping/
bucket.rs1use 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}