more_itertools/itertools/
groupby.rs1use std::collections::VecDeque;
2use std::fmt::Debug;
3use crate::utils::are_same;
4
5pub struct GroupBy<T>
6where T: Clone + Debug + PartialEq
7{
8 cur_key: Option<T>,
9 buf: VecDeque<T>,
10 emitted_first: bool,
11 iter: Box<dyn Iterator<Item = T>>,
12 iter_finished: bool,
13 stop_next: bool,
14}
15
16
17impl<T> GroupBy<T>
18where T: Clone + Debug + PartialEq
19{
20 pub fn next_group(&mut self) -> Option<T> {
21 loop {
22 if self.iter_finished {
23 return None;
24 }
25
26 let _next;
27 if self.buf.len() > 0 {
28 _next = self.buf.pop_front();
29 } else {
30 _next = self.iter.next();
31 }
32
33 match _next {
34 None => {
35 self.iter_finished = true;
36 continue;
37 },
38 Some(v) => {
39 if self.cur_key.is_none() || !are_same(Some(&v), Some(self.cur_key.as_mut().unwrap())) {
40 self.cur_key = Some(v.clone());
41 self.emitted_first = false;
42 self.stop_next = false;
43 return Some(v);
44 } else {
45 continue;
46 }
47 }
48 }
49 }
50 }
51
52 pub fn collect0(&mut self) -> Vec<T> {
53 return self.collect();
54 }
55}
56
57impl<T> Iterator for GroupBy<T>
58where
59T: PartialEq + Clone + Debug
60{
61 type Item = T;
62
63 fn next(&mut self) -> Option<Self::Item> {
64 loop {
65 if self.iter_finished {
66 return None;
67 }
68
69 if self.stop_next {
70 return None;
71 }
72
73 if self.cur_key.is_none() {
74 return None;
75 }
76
77 if !self.emitted_first {
78 self.emitted_first = true;
79 return Some(self.cur_key.as_ref().unwrap().clone());
80 }
81
82 let _next = self.iter.next();
83 match _next {
84 None => {
85 self.iter_finished = true;
86 continue;
87 },
88 Some(v) => {
89 if !are_same(Some(&v), Some(self.cur_key.as_mut().unwrap())) {
90 self.buf.push_back(v.clone());
91 self.stop_next = true;
92 continue;
93 } else {
94 return Some(v);
95 }
96 }
97 }
98 }
99 }
100}
101
102pub fn groupby<T>(iter: Box<dyn Iterator<Item = T>>) -> GroupBy<T>
103where
104T: PartialEq + Clone + Debug
105{
106 return GroupBy {
107 cur_key: None,
108 buf: VecDeque::new(),
109 emitted_first: false,
110 iter,
111 iter_finished: false,
112 stop_next: true
113 }
114}
115
116
117#[cfg(test)]
118mod tests {
119 use crate::itertools::iter::iter_from_vec;
120
121 use super::*;
122
123 #[test]
124 fn test1() {
125 let mut ret = groupby(iter_from_vec("AAAAbbbcccC".chars().collect::<Vec<char>>()));
126 assert_eq!('A', ret.next_group().unwrap());
127 assert_eq!(vec!['A','A','A','A'], ret.collect0());
128 assert_eq!(None, ret.next());
129
130 assert_eq!('b', ret.next_group().unwrap());
131 assert_eq!(vec!['b','b','b'], ret.collect0());
132 assert_eq!(None, ret.next());
133
134 assert_eq!('c', ret.next_group().unwrap());
135 assert_eq!(vec!['c','c','c'], ret.collect0());
136 assert_eq!(None, ret.next());
137
138 assert_eq!('C', ret.next_group().unwrap());
139 assert_eq!(vec!['C'], ret.collect0());
140 assert_eq!(None, ret.next());
141 }
142
143 #[test]
144 fn test2() {
145 let mut ret = groupby(iter_from_vec("0AAAAbbbcccCC".chars().collect::<Vec<char>>()));
146 assert_eq!('0', ret.next_group().unwrap());
147 assert_eq!(vec!['0'], ret.collect0());
148 assert_eq!(None, ret.next());
149
150 assert_eq!('A', ret.next_group().unwrap());
151 assert_eq!(vec!['A','A','A','A'], ret.collect0());
152 assert_eq!(None, ret.next());
153
154 assert_eq!('b', ret.next_group().unwrap());
155 assert_eq!(vec!['b','b','b'], ret.collect0());
156 assert_eq!(None, ret.next());
157
158 assert_eq!('c', ret.next_group().unwrap());
159 assert_eq!(vec!['c','c','c'], ret.collect0());
160 assert_eq!(None, ret.next());
161
162 assert_eq!('C', ret.next_group().unwrap());
163 assert_eq!(vec!['C','C'], ret.collect0());
164 assert_eq!(None, ret.next());
165 }
166
167 #[test]
168 fn test3() {
169 let mut ret = groupby(iter_from_vec("0AAAAbbbcccCC".chars().collect::<Vec<char>>()));
170 assert_eq!('0', ret.next_group().unwrap());
171
172 assert_eq!('A', ret.next_group().unwrap());
173
174 assert_eq!(vec!['A','A','A','A'], ret.collect0());
175 assert_eq!(None, ret.next());
176
177 assert_eq!('b', ret.next_group().unwrap());
178 assert_eq!(vec!['b','b','b'], ret.collect0());
179 assert_eq!(None, ret.next());
180
181 assert_eq!('c', ret.next_group().unwrap());
182 assert_eq!(vec!['c','c','c'], ret.collect0());
183 assert_eq!(None, ret.next());
184
185 assert_eq!('C', ret.next_group().unwrap());
186 assert_eq!(vec!['C','C'], ret.collect0());
187 assert_eq!(None, ret.next());
188 }
189}