math/iter/
concatenated_iter.rs

1pub struct ConcatenatedIter<I: Iterator> {
2    iters: Vec<I>,
3    current_iter_index: usize,
4}
5
6impl<I: Iterator> ConcatenatedIter<I> {
7    pub fn from_iters(iters: Vec<I>) -> Self {
8        ConcatenatedIter {
9            iters,
10            current_iter_index: 0,
11        }
12    }
13
14    pub fn concat_iter(self, other: I) -> Self {
15        let mut iters = self.iters;
16        iters.push(other);
17        ConcatenatedIter {
18            iters,
19            current_iter_index: self.current_iter_index,
20        }
21    }
22}
23
24impl<I: Iterator> From<Vec<I>> for ConcatenatedIter<I> {
25    fn from(iters: Vec<I>) -> Self {
26        Self::from_iters(iters)
27    }
28}
29
30impl<I: Iterator> Iterator for ConcatenatedIter<I> {
31    type Item = <I as Iterator>::Item;
32
33    fn next(&mut self) -> Option<Self::Item> {
34        match self.iters.get_mut(self.current_iter_index) {
35            None => None,
36            Some(iter) => match iter.next() {
37                Some(x) => Some(x),
38                None => {
39                    self.current_iter_index += 1;
40                    self.next()
41                }
42            },
43        }
44    }
45}
46
47pub trait IntoConcatIter: Iterator + Sized {
48    fn into_concat_iter(self, other: Self) -> ConcatenatedIter<Self> {
49        ConcatenatedIter {
50            iters: vec![self, other],
51            current_iter_index: 0,
52        }
53    }
54}
55
56impl<I: Iterator + Sized> IntoConcatIter for I {}
57
58#[cfg(test)]
59mod tests {
60    use crate::iter::{concatenated_iter::IntoConcatIter, ConcatenatedIter};
61    use std::collections::BTreeMap;
62
63    #[test]
64    fn test_from_iters() {
65        let arr1 = vec![0, 1, 2];
66        let arr2 = vec![3, 4];
67        let arr3 = vec![5, 6];
68        let mut concat_iter =
69            ConcatenatedIter::from(vec![arr1.iter(), arr2.iter(), arr3.iter()]);
70        assert_eq!(concat_iter.next(), Some(&0));
71        assert_eq!(concat_iter.next(), Some(&1));
72        assert_eq!(concat_iter.next(), Some(&2));
73        assert_eq!(concat_iter.next(), Some(&3));
74        assert_eq!(concat_iter.next(), Some(&4));
75        assert_eq!(concat_iter.next(), Some(&5));
76        assert_eq!(concat_iter.next(), Some(&6));
77        assert_eq!(concat_iter.next(), None);
78    }
79
80    #[test]
81    fn test_concat_vec_iter() {
82        let arr1 = vec![0, 1, 2];
83        let arr2 = vec![3, 4];
84        let arr3 = vec![6, 7, 8];
85        {
86            let mut concat_1_2 = arr1.iter().into_concat_iter(arr2.iter());
87            assert_eq!(concat_1_2.next(), Some(&0));
88            assert_eq!(concat_1_2.next(), Some(&1));
89            assert_eq!(concat_1_2.next(), Some(&2));
90            assert_eq!(concat_1_2.next(), Some(&3));
91            assert_eq!(concat_1_2.next(), Some(&4));
92            assert_eq!(concat_1_2.next(), None);
93        }
94        {
95            let mut concat_1_2 = arr1.iter().into_concat_iter(arr2.iter());
96            assert_eq!(concat_1_2.next(), Some(&0));
97            assert_eq!(concat_1_2.next(), Some(&1));
98            concat_1_2 = concat_1_2.concat_iter(arr3.iter());
99            assert_eq!(concat_1_2.next(), Some(&2));
100            assert_eq!(concat_1_2.next(), Some(&3));
101            assert_eq!(concat_1_2.next(), Some(&4));
102            assert_eq!(concat_1_2.next(), Some(&6));
103            assert_eq!(concat_1_2.next(), Some(&7));
104            concat_1_2 = concat_1_2.concat_iter(arr3.iter());
105            assert_eq!(concat_1_2.next(), Some(&8));
106            assert_eq!(concat_1_2.next(), Some(&6));
107            assert_eq!(concat_1_2.next(), Some(&7));
108            assert_eq!(concat_1_2.next(), Some(&8));
109            concat_1_2 = concat_1_2.concat_iter(arr1.iter());
110            assert_eq!(concat_1_2.next(), Some(&0));
111            assert_eq!(concat_1_2.next(), Some(&1));
112            assert_eq!(concat_1_2.next(), Some(&2));
113            assert_eq!(concat_1_2.next(), None);
114        }
115    }
116
117    #[test]
118    fn test_concat_btreemap_iter() {
119        let m1: BTreeMap<i32, i32> = vec![(1, 2), (3, 4)].into_iter().collect();
120        let m2: BTreeMap<i32, i32> =
121            vec![(11, 12), (13, 14), (15, 16)].into_iter().collect();
122        let mut iter = m1.iter().into_concat_iter(m2.iter());
123        assert_eq!(iter.next(), Some((&1, &2)));
124        assert_eq!(iter.next(), Some((&3, &4)));
125        assert_eq!(iter.next(), Some((&11, &12)));
126        assert_eq!(iter.next(), Some((&13, &14)));
127        assert_eq!(iter.next(), Some((&15, &16)));
128    }
129}