Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
613: Minmax set (prev "Add {min,max}_set(_by{_key)?)? functions") r=jswrenn a=phimuemue This PR supersedes #323 (I did not know how I could amend to the original PR, so sorry for the "duplicate" PR here.) The original PR by `@zayenz` looked rather good. I adjusted the stuff that came up during discussion back then: * Teturn type `Vec` instead of `Option` - emptiness is sufficiently well represented by `Vec`. * Functions require `Ord` instead of `PartialOrd` - just as `Iterator::min`. * Avoid duplicate calls to `lt` by accepting a `FnMut(...)->Ordering` - seems canonical compared to the `bool`-solution. * Use internal iteration instead of a manual `for`-loop. Moreover, I simplified some bits. Co-authored-by: Mikael Zayenz Lagerkvist <zayenz@gmail.com> Co-authored-by: philipp <descpl@yahoo.de>
- Loading branch information
Showing
4 changed files
with
346 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use std::cmp::Ordering; | ||
|
||
/// Implementation guts for `min_set`, `min_set_by`, and `min_set_by_key`. | ||
pub fn min_set_impl<I, K, F, Compare>( | ||
mut it: I, | ||
mut key_for: F, | ||
mut compare: Compare, | ||
) -> Vec<I::Item> | ||
where | ||
I: Iterator, | ||
F: FnMut(&I::Item) -> K, | ||
Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering, | ||
{ | ||
match it.next() { | ||
None => Vec::new(), | ||
Some(element) => { | ||
let mut current_key = key_for(&element); | ||
let mut result = vec![element]; | ||
it.for_each(|element| { | ||
let key = key_for(&element); | ||
match compare(&element, &result[0], &key, ¤t_key) { | ||
Ordering::Less => { | ||
result.clear(); | ||
result.push(element); | ||
current_key = key; | ||
} | ||
Ordering::Equal => { | ||
result.push(element); | ||
} | ||
Ordering::Greater => {} | ||
} | ||
}); | ||
result | ||
} | ||
} | ||
} | ||
|
||
/// Implementation guts for `ax_set`, `max_set_by`, and `max_set_by_key`. | ||
pub fn max_set_impl<I, K, F, Compare>(it: I, key_for: F, mut compare: Compare) -> Vec<I::Item> | ||
where | ||
I: Iterator, | ||
F: FnMut(&I::Item) -> K, | ||
Compare: FnMut(&I::Item, &I::Item, &K, &K) -> Ordering, | ||
{ | ||
min_set_impl(it, key_for, |it1, it2, key1, key2| { | ||
compare(it2, it1, key2, key1) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters