toolbox_rs/
run_iterator.rs

1pub struct RunIterator<'a, T> {
2    array: &'a [T],
3    pos: usize,
4}
5
6impl<'a, T: PartialEq> RunIterator<'a, T> {
7    pub fn new(array: &'a [T]) -> Self {
8        RunIterator { array, pos: 0 }
9    }
10}
11
12impl<'a, T: PartialEq> Iterator for RunIterator<'a, T> {
13    type Item = &'a [T];
14
15    fn next(&mut self) -> Option<Self::Item> {
16        if self.pos >= self.array.len() {
17            return None;
18        }
19
20        let start = self.pos;
21        self.pos += 1;
22
23        self.pos += self.array[start + 1..]
24            .iter()
25            .position(|x| x != &self.array[start])
26            .unwrap_or(self.array.len() - start - 1);
27
28        Some(&self.array[start..self.pos])
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::RunIterator;
35    #[test]
36    fn unsorted_runs_tests() {
37        let array = [1, 1, 2, 2, 2, 3, 3, 1];
38        let run_iter = RunIterator::new(&array);
39
40        let result: Vec<&[i32]> = run_iter.collect();
41        let expected: Vec<&[i32]> = vec![&[1; 2], &[2; 3], &[3; 2], &[1; 1]];
42        assert_eq!(expected, result);
43    }
44
45    #[test]
46    fn object_runs() {
47        #[derive(Debug)]
48        struct SimplePair {
49            key: i32,
50            _value: i32,
51        }
52
53        impl PartialEq for SimplePair {
54            fn eq(&self, other: &Self) -> bool {
55                self.key == other.key
56            }
57        }
58
59        let runs = vec![
60            SimplePair { key: 1, _value: 2 },
61            SimplePair { key: 1, _value: 1 },
62            SimplePair { key: 21, _value: 1 },
63            SimplePair { key: 1, _value: 1 },
64        ];
65
66        let run_iter = RunIterator::new(&runs);
67
68        let result: Vec<&[SimplePair]> = run_iter.collect();
69        assert_eq!(3, result.len());
70        let expected = vec![&runs[0..2], &runs[2..3], &runs[3..]];
71        assert_eq!(expected, result);
72    }
73}