itertools/
extrema_set.rs

1use std::cmp::Ordering;
2
3/// Implementation guts for `min_set`, `min_set_by`, and `min_set_by_key`.
4pub fn min_set_impl<I, K, F, Compare>(
5    mut it: I,
6    mut key_for: F,
7    mut compare: Compare,
8) -> Vec<I::Item>
9where
10    I: Iterator,
11    F: FnMut(&I::Item) -> K,
12    Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering,
13{
14    match it.next() {
15        None => Vec::new(),
16        Some(element) => {
17            let mut current_key = key_for(&element);
18            let mut result = vec![element];
19            it.for_each(|element| {
20                let key = key_for(&element);
21                match compare(&element, &result[0], &key, &current_key) {
22                    Ordering::Less => {
23                        result.clear();
24                        result.push(element);
25                        current_key = key;
26                    }
27                    Ordering::Equal => {
28                        result.push(element);
29                    }
30                    Ordering::Greater => {}
31                }
32            });
33            result
34        }
35    }
36}
37
38/// Implementation guts for `ax_set`, `max_set_by`, and `max_set_by_key`.
39pub fn max_set_impl<I, K, F, Compare>(it: I, key_for: F, mut compare: Compare) -> Vec<I::Item>
40where
41    I: Iterator,
42    F: FnMut(&I::Item) -> K,
43    Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering,
44{
45    min_set_impl(it, key_for, |it1, it2, key1, key2| {
46        compare(it2, it1, key2, key1)
47    })
48}