-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Implement minmax #5268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
nominating to remove from milestone 2. it's nice code, happy to take it, but purely backward-compatible addition. |
just a bug, removing milestone/nomination. |
Triage. My linked implementation is obsolete because it predates the current Rust iterator. It would be still nice to have minmax, and it should be much easier to implement now. |
I'll look into it if no one wants to. |
https://gist.github.com/pongad/8270459 |
My implementation is now working |
@pongad not failing on an empty iterator would be good (i.e. returning enum MinMax<T> {
// Empty iterator
NoElements,
// Iterator with one element, so the minimum and maximum are the same (and
// without Clone we can't make two copies of it)
OneElement(T)
// More than one element in the iterator, so we can store them separated
MinMax(T, T)
} |
@huonw Made a version to address your concern Also, is there a better way to do what I did without the is_none/unwrap "pattern"? |
(BTW, Rust has built-in micro-benchmarking: https://github.com/mozilla/rust/wiki/Doc-unit-testing#benchmarking ) And yes, definitely, let x = match me.next() {
None => { ...; break } // (or return)
Some(x) => x
} However, I think a more global rewrite may be better: fn minmax<T: Ord, A: Iterator<T>>(me: &mut A) -> MinMax<T> {
let (mut min, mut max) = match me.next() {
None => return NoElements,
Some(x) => {
match me.next() {
None => return OneElement(x),
Some(y) => if x <= y {(x, y)} else {(y, x)}
}
}
}
for new in me.iter() {
if new < min { min = new; }
else if new > max { max = new; }
}
MinMax(min, max)
} |
Of course! Though I think the point of @sanxiyn original implementation is to guarantee 1.5n comparisons. Your implementation will take 2n if the elements are increasing. It will take 1n if the elements are decreasing though. I don't know what to think anymore!!! |
Oh I see! A similar thing should be possible by changing my let left_over;
loop {
let first = match me.next() {
None => { left_over = None; break }
Some(x) => x
});
let second = match me.next() {
None => { left_over = Some(first); break }
Some(x) => x
};
// do the comparisons to adjust min and max
}
match left_over {
None = > MinMax(min, max)
Some(x) => {
// do the comparisons for the trailing element
}
} |
Updated again from @huonw 's comments. A question though, what about [5,5,5,5]? Should we make special case to return OneElement? |
@pongad IMO, I say return the (The decision here is not entirely arbitrary; I'm assuming that it is easier/cheaper to inspect the |
https://gist.github.com/pongad/8270459 |
Isn't this meant to be on |
Clean-up docs Fixes rust-lang#5268 changelog: none
…022-03-16 subtree sync
C++11 introduced minmax_element.
Preliminary implementation here: https://mail.mozilla.org/pipermail/rust-dev/2013-March/003328.html
The text was updated successfully, but these errors were encountered: