我想访问
Vec<i32>
中最大元素旁边的元素。我正在寻找这样的东西:
let v = vec![1, 3, 2];
let it = v.iter().max_element();
assert_eq!(Some(&2), it.next());
在 C++ 中,我会使用
std::max_element
,然后只增加迭代器(有或没有边界检查,取决于我目前的冒险精神)。 Rust max
仅返回对元素的引用,这对于我的用例来说不够好。
我想到的唯一解决方案是使用
enumerate
来获取项目的索引 - 但与 C++ 方式相比,这似乎是手动且麻烦的。
我更喜欢标准库中的东西。
这个例子是简化的 - 我实际上想附加到最高值,然后从该点循环整个容器(可能使用
cycle()
或类似的东西)。
一个简单的解决方案是使用折叠, 以下代码生成“最大数字是:99”
let vv:Vec<i32> = (1..100).collect();
let largest = vv.iter().fold(std::i32::MIN, |a,b| a.max(*b));
println!("largest {} ", largest);
C++ 迭代器与 Rust 迭代器不同。 Rust 迭代器是只向前的,并且只能遍历一次。 C++ 迭代器可以被认为是游标。有关更多详细信息,请参阅Rust 迭代器和 C++ 迭代器之间的主要区别是什么?。
为了以最通用的方式实现您的目标,您必须遍历整个迭代器以找到最大值。在此过程中,每次找到新的最大值时,您都必须复制迭代器。最后可以返回最大值之后的点对应的迭代器。
trait MaxElement {
type Iter;
fn max_element(self) -> Self::Iter;
}
impl<I> MaxElement for I
where
I: Iterator + Clone,
I::Item: PartialOrd,
{
type Iter = Self;
fn max_element(mut self) -> Self::Iter {
let mut max_iter = self.clone();
let mut max_val = None;
while let Some(val) = self.next() {
if max_val.as_ref().map_or(true, |m| &val > m) {
max_iter = self.clone();
max_val = Some(val);
}
}
max_iter
}
}
fn main() {
let v = vec![1, 3, 2];
let mut it = v.iter().max_element();
assert_eq!(Some(&2), it.next());
}
另请参阅:
我实际上想附加到最高值,然后从该点循环整个容器(可能使用
或类似的东西)。cycle()
在这种情况下,我会尝试更明显:
fn index_of_max(values: &[i32]) -> Option<usize> {
values
.iter()
.enumerate()
.max_by_key(|(_idx, &val)| val)
.map(|(idx, _val)| idx)
}
fn main() {
let v = vec![1, 3, 2];
let idx = index_of_max(&v).unwrap_or(0);
let (a, b) = v.split_at(idx);
let mut it = b.iter().chain(a).skip(1);
assert_eq!(Some(&2), it.next());
}
另请参阅:
如果您想要的只是最大值之后的项目的值,我会通过简单地调用
fold
来完成,跟踪迄今为止找到的最大值以及相应的下一个值:
fn main() {
let v = vec![1, 3, 2];
let nxt = v.iter().fold (
(None, None),
|acc, x| {
match acc {
(Some (max), _) if x > max => (Some (x), None),
(Some (max), None) => (Some (max), Some (x)),
(None, _) => (Some (x), None),
_ => acc
}
}
).1;
assert_eq!(Some(&2), nxt);
}
根据您想要对最大值之后的项目执行的操作,类似的方法可能允许您一次性完成。
找到
max_num
的索引,然后创建一个新的迭代器并跳过它。
fn main() {
let nums = vec![1, 3, 2];
let max_num = nums.iter().max().unwrap();
let max_num_index = nums.iter().position(|num| num == max_num).unwrap();
let max_num_it = nums.iter().skip(max_num_index);
assert_eq!(Some(&2), max_num_it.skip(1).next());
}
在本例中,您使用的是 Vec,它可以通过索引有效地获取元素。
同时找到
max_num_index
、max_num
并使用下一个索引来获取下一个元素会更快。
fn main() {
let nums = vec![1, 3, 2];
let (max_num_index, _max_num) = nums
.iter()
.enumerate()
.max_by_key(|(_i, &num)| num)
.unwrap();
assert_eq!(Some(&2), nums.get(max_num_index + 1));
}