考虑一般的
Ord
类型的简单情况:答案会略有不同,具体取决于您是否知道这些值是
Copy
的,但以下是代码:
fn position_max_copy<T: Ord + Copy>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by_key(|(_, &value)| value).map(|(idx, _)| idx)
}
fn position_max<T: Ord>(slice: &[T]) -> Option<usize> {
slice.iter().enumerate().max_by(|(_, value0), (_, value1)| value0.cmp(value1)).map(|(idx, _)| idx)
}
基本思路是将数组中的每个项(实际上是一个切片——无论它是Vec还是数组或其他更奇特的东西)与其索引配对,使用std::iter::Iterator函数仅根据值(而不是索引)查找最大值,然后仅返回索引。如果切片为空,则返回None。根据文档,将返回最右侧的索引;如果需要最左侧的索引,请在enumerate()之后执行rev()。
rev()
、enumerate()
、max_by_key()
和max_by()
在这里有文档说明;slice::iter()
在这里有文档说明(但作为rust开发人员,这应该是你需要记住的东西之一);map
是Option::map()
,在这里有文档说明(同上)。哦,而cmp
是Ord::cmp
,但大多数情况下,您可以使用不需要它的Copy
版本(例如,如果您正在比较整数)。
现在有一个问题: 由于IEEE浮点数的工作方式,
f32
并不是
Ord
。大多数语言都忽略了这一点,并且算法存在微妙的错误。提供
Ord
总序(通过将所有NaN声明为相等,并大于所有数字)最流行的箱子似乎是
ordered-float。假设它实现正确,它应该非常轻量级。它确实调用了
num_traits
,但这是最流行的数字库的一部分,因此可能已经被其他依赖项调用。
您可以通过在切片迭代器上映射ordered_float::OrderedFloat
(元组类型的“构造函数”)来在这种情况下使用它(slice.iter().map(ordered_float::OrderedFloat)
)。由于只想要最大元素的位置,因此无需在之后提取f32。
Vec
? - jhpratt