如何检查for循环是否在迭代器的最后一个元素上?

koo*_*mes 2 rust

我试图找到一种方法来检查我是否在 for 循环中的迭代器的最后一个元素上,而不使用 .clone(); 目前我正在这样做:

let sentence = "The quick brown fox.";
let words = sentence.split(' ');
let last = words.clone().last().unwrap();
 
for word in words {
    if word == last {
        print!("{}", word);
    }
} 
Run Code Online (Sandbox Code Playgroud)

我也试过在迭代器上使用 .collect() ,但这要求我使用 .iter().enumerate() 来检查最后一个索引,这对我来说似乎不必要地复杂:

let sentence = "The quick brown fox.";
let words: Vec<&str> = sentence.split(' ').collect();
 
for (i, word) in words.iter().enumerate() {
    if i == words.len() - 1 {
        print!("{}", word);
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法以更简洁的方式做到这一点,也许只是使用原始迭代器?

Mas*_*inn 7

将您的迭代器转换为Peekable.

这将需要将迭代脱糖为 a while let,但如果在迭代期间peek()返回,则None您处于最后一次迭代:

let mut it = sentence.split(' ').peekable();
while let Some(word) = it.next()  {
    if it.peek().is_none() {
        println!("{}", word);
    }
}
Run Code Online (Sandbox Code Playgroud)

游乐场


Den*_*ret 6

对于有限迭代器的一般情况,如果您想获得最后一项,您可以按照@Masklinn(请参阅他们的答案)的建议,转换为Peekable将缓冲的a ,以便它始终知道下一个元素。

在您的具体情况下,当你只是要打印的最后一个字,不关心其他的,还有因为分裂的角色实现了一个便宜得多的解决方案DoubleEndedIterator

所以很容易得到最后一个词,您不必收集整个拆分或枚举。它也很快,因为将从末尾搜索字符串并且不会复制任何内容。

所以你可以做

let last_word = sentence
    .split(' ').rev().next().unwrap(); // SAFETY: there's always at least one word
Run Code Online (Sandbox Code Playgroud)

  • 通过“peekable”有一个完全通用的解决方案(当然,如果输入无限迭代器,结果可能会出乎意料)。 (2认同)