Assumption -- The Vec
does not have any NaN
values or exhibit any NaN
behavior.
T
The reason why this is tricky is because f32
does not implement Ord
. That is because NaN
values prevent floating point numbers from forming a total order, which violates the contract of Ord
.
There are 3rd party crates that work around this by defining a numeric type wrapper which is not allowed to contain a NaN
. One example is ordered-float. If you use this crate to first prepare the collection to contain NotNan
values, then you can write code very close to your original idea:
use ordered_float::NotNan;
let non_nan_floats: Vec<_> = nets.iter()
.cloned()
.map(NotNan::new) // Attempt to convert each f32 to a NotNan
.filter_map(Result::ok) // Unwrap the `NotNan`s and filter out the `NaN` values
.collect();
let max = non_nan_floats.iter().max().unwrap();
let index = non_nan_floats.iter().position(|element| element == max).unwrap();
Add this to Cargo.toml
:
[dependencies]
ordered-float = "1.0.1"
Bonus material: The type conversion can be made truly zero-cost (assuming you are really sure that there are no NaN
values!), by taking advantage of the fact that NotNan
has a transparent representation:
let non_nan_floats: Vec> = unsafe { mem::transmute(nets) };