如何从迭代器循环内跳过n个项目?

时间:2019-11-26 07:02:19

标签: rust iterator

此代码:

play

fn main() {
    let text = "abcd";

    for char in text.chars() {
        if char == 'b' {
            // skip 2 chars
        }
        print!("{}", char);
    }
    // prints `abcd`, but I want `ad`
}

打印abcd,但是如果找到b,我想跳过2个字符,以便打印ad。我怎么做?

我试图将迭代器放入循环外的变量中,并在循环内操作该迭代器,但借阅检查器不允许这样做。

2 个答案:

答案 0 :(得分:5)

AFAIK,您无法使用for循环来做到这一点。您需要手工对其进行除糖:

let mut it = text.chars();
while let Some(char) = it.next() {
    if char == 'b' {
        it.nth(1); // nth(1) skips/consumes exactly 2 items
        continue;
    }
    print!("{}", char);
}

Playground

答案 1 :(得分:2)

如果要保留迭代器样式,则可以使用std::iter::successors(为了更易读,我用'!'替换了特殊字符:

fn my_iter<'a>(s: &'a str) -> impl Iterator<Item = char> + 'a {
    let mut it = s.chars();

    std::iter::successors(it.next(), move |c| {
        if *c == '!' {
            it.next().and_then(|_| it.next())
        } else {
            it.next()
        }
    })
    .filter(|c| *c != '!')
}

fn main() {
    assert!(my_iter("a!bc").eq("ac".chars()));
    assert!(my_iter("!abcd").eq("bcd".chars()));
    assert!(my_iter("abc!d").eq("abc".chars()));
    assert!(my_iter("abcd!").eq("abcd".chars()));
}