Reputation: 9815
I have a vector of prices (f64
). I would like to compute the highest price.
What is the current easiest and most idiomatic way to compute the max of a collection of f64
in rust ?
There has been some discussion about Ord
and f64
but I am not sure what is the most up-to-date and less hacky way to do so.
I rely on the following but I imagined there was some built in operation
let max = prices.iter().fold(None, |r, &n| match r {
Some(p) => Some(f64::max(p, n)),
None => Some(e),
});
(which is just a fold for some free monoid)
Upvotes: 19
Views: 11925
Reputation: 1440
As yet another alternative, since Rust 1.59, there's a total_cmp
method on f32
and f64
that you could use with max_by
.
arr.iter().max_by(|a, b| a.total_cmp(b))
Upvotes: 18
Reputation: 1530
Here's a clean way to do it with an actual vector and no copy operation:
fn main() {
let v: Vec<f64> = vec![-2.2, -7.7, -3.3];
let max = v
.iter()
.fold(f64::NEG_INFINITY, |prev, curr| prev.max(*curr));
assert!(max == -2.2);
println!("{}", max);
}
Upvotes: 1
Reputation: 300
As of Rust 1.43, you can write this:
my_iterator.fold(f64::NEG_INFINITY, f64::max)
Explanation: use f64::NEG_INFINITY
as the initial value, as it is the neutral element for the f64::max
operation.
Upvotes: 10
Reputation: 58805
An alternative solution, using the popular ordered-float
crate, allows you to use the built-in Iterator::max
method:
use ordered_float::NotNan; // 2.0.0
let max = arr
.iter()
.copied()
.map(NotNan::new)
.flatten() // ignore NAN values (errors from the previous line)
.max()
.map(NotNan::into_inner);
This is essentially the same as the idiomatic code you would write to find the maximum value from an array of integers:
let max = arr.iter().copied().max();
The difference is that it adds a NotNan
wrapper around each value, which implements Ord
. After the result is found, it unwraps the values to get at the inner float. You can apply this pattern to most existing code that works with integers, to update it to work with floats instead.
Upvotes: 6
Reputation: 5575
I'm unaware of different ways to do so, but I've used the following in the past:
let arr = [1.0, -42.0, 0.0, -5.0, 42.0, 7.0];
let max = arr.iter().copied().fold(f64::NAN, f64::max) // 42.0
Upvotes: 13