more_itertools/grouping/
partition.rs1use std::rc::Rc;
2
3use crate::sequence::Sequence;
4
5
6pub struct PartitionInner<T> {
7 buf: Box<dyn Sequence<T>>,
8 pred: fn(&T) -> bool
9}
10
11pub struct Partition<T> {
12 inner: Rc<PartitionInner<T>>
13}
14
15pub struct CursorFalse<T> {
16 inner: Rc<PartitionInner<T>>,
17 _next: usize
18}
19
20pub struct CursorTrue<T> {
21 inner: Rc<PartitionInner<T>>,
22 _next: usize
23}
24
25impl<T> Iterator for CursorFalse<T>
26where
27T: Clone
28{
29 type Item = T;
30
31 fn next(&mut self) -> Option<Self::Item> {
32 loop {
33 if self._next >= self.inner.buf.len() {
34 return None;
35 }
36 let t = self.inner.buf.get(self._next).unwrap();
37 self._next += 1;
38 if !(self.inner.pred)(t) {
39 return Some(t.clone());
40 }
41 }
42 }
43}
44
45impl<T> Iterator for CursorTrue<T>
46where
47T: Clone
48{
49 type Item = T;
50
51 fn next(&mut self) -> Option<Self::Item> {
52 loop {
53 if self._next >= self.inner.buf.len() {
54 return None;
55 }
56 let t = self.inner.buf.get(self._next).unwrap();
57 self._next += 1;
58 if (self.inner.pred)(t) {
59 return Some(t.clone());
60 }
61 }
62 }
63}
64
65impl<T> Partition<T>
66where T: Clone + 'static
67{
68 pub fn new(buf: Box<dyn Sequence<T>>, pred: fn(&T) -> bool) -> Partition<T> {
69 let inner = PartitionInner {
70 buf: buf,
71 pred: pred
72 };
73
74 let ret = Partition {
75 inner: Rc::new(inner)
76 };
77
78 return ret;
79 }
80
81 pub fn get_cursor(&self) -> (Box<dyn Iterator<Item = T>>, Box<dyn Iterator<Item = T>>){
82 let cur_false: Box<dyn Iterator<Item = T>> = Box::new(CursorFalse {
83 inner: Rc::clone(&self.inner),
84 _next: 0
85 });
86 let cur_true: Box<dyn Iterator<Item = T>> = Box::new(CursorTrue {
87 inner: Rc::clone(&self.inner),
88 _next: 0
89 });
90 return (cur_false, cur_true);
91 }
92}
93
94pub fn partition<T>(buf: Box<dyn Sequence<T>>, pred: fn(&T) -> bool) -> (Box<dyn Iterator<Item = T>>, Box<dyn Iterator<Item = T>>)
95where T: Clone + 'static
96{
97 let p = Partition::new(buf, pred);
98 return p.get_cursor();
99}
100
101
102#[cfg(test)]
103mod tests {
104 use crate::sequence::create_seq_from_vec;
105
106 use super::*;
107
108 #[test]
109 fn test1() {
110 let v = vec![1,2,3,4,5,6,7,8,9,10];
111
112 let (cur_false, cur_true) = partition(create_seq_from_vec(v), |x| {x % 2 == 1});
113 assert_eq!(vec![2, 4, 6, 8, 10], cur_false.collect::<Vec<_>>());
114 assert_eq!(vec![1, 3, 5, 7, 9], cur_true.collect::<Vec<_>>());
115 }
116}