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

e4eetjau  于 2023-04-30  发布在  其他
关注(0)|答案(4)|浏览(167)

我试图找到一种方法来检查我是否在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);
    }
}

我也试过用。在迭代器上使用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);
    }
}

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

p8ekf7hl

p8ekf7hl1#

将迭代器转换为Peekable
这将需要将迭代去糖为while let,但如果在迭代过程中peek()返回None,则您处于最后一次迭代:

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

Playground

3okqufwl

3okqufwl2#

对于有限迭代器的一般情况,如果你想得到最后一个元素,你可以像@Masklinn建议的那样(见他们的答案),转换为一个Peekable,它将缓冲,所以它总是知道下一个元素。
在您的具体情况下,当您只想打印最后一个单词而不关心其他单词时,有一个更便宜的解决方案,因为在字符上分割实现了DoubleEndedIterator
所以很容易得到最后一个词,你不必收集整个分裂或列举。它也很快,因为字符串将从末尾开始搜索,并且不会复制任何东西。
所以你可以

let last_word = sentence
    .split(' ').rev().next().unwrap(); // SAFETY: there's always at least one word
dfddblmv

dfddblmv3#

您可以利用Iterator::map()迭代器适配器来实现更方便的使用:

let sentence = "The quick brown fox.";
let words: Vec<&str> = sentence.split(' ').collect();

for (word, is_last_element) in words.iter().enumerate()
  .map(|(i, w)| (w, i == words.len() - 1))
{
   if is_last_element {
      println!("{}", word);
   }
}

这样,就不必处理循环体中的索引,只需关注特定迭代中的给定元素是否是最后一个。

6mw9ycah

6mw9ycah4#

我想补充@Masklinn的回答。
我使用了一个特性来使它更具可读性。
代码允许将it.peek().is_none()写成it.is_last()

trait IterEndPeek {
    fn is_last(&mut self) -> bool;
}

impl<I: Iterator> IterEndPeek for  std::iter::Peekable<I> {
    fn is_last(&mut self) -> bool {
        self.peek().is_none()
    }
}

fn main() {
    let sentence = "The quick brown fox.";
    let mut it = sentence.split(' ').peekable();
    while let Some(word) = it.next()  {
        if it.is_last() {
            println!("last {}", word);
        } else {
            println!("- {}", word);
        }
    }
}

相关问题