Причина, по которой это сложно, заключается в том, что f32
не реализует Ord
.Это связано с тем, что значения NaN
препятствуют формированию общего порядка чисел с плавающей запятой, что нарушает контракт Ord
.
. Существуют ящики сторонних производителей, которые обходят это путем определения обертки числового типа, которая не являетсяразрешено содержать NaN
.Одним из примеров является orders-float .Если вы используете этот ящик, чтобы сначала подготовить коллекцию, содержащую NotNan
значений, то вы можете написать код, очень близкий к исходной идее:
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();
Добавьте это к Cargo.toml
:
[dependencies]
ordered-float = "1.0.1"
Бонусный материал : преобразование типов может быть сделано по-настоящему без затрат (при условии, что вы действительно уверены, что нет NaN
значения!), используя тот факт, что NotNan
имеет прозрачное представление:
let non_nan_floats: Vec<NotNan<f32>> = unsafe { mem::transmute(nets) };