[solved] How do I use the same iterator twice?

I have something like:

fn foo<TIterator>(items: TIterator)
    where TIterator: Iterator<Item = Bar> {
    for item in items {
        // use item
    }

    // do other stuff

    for item in items {
        // use item
    }
}

But my code fails to compile because items is moved in the first for loop. The type Bar is Clone if that helps. In particular, Bar is an Rc to the actual item and I want to store copies of the Rcs in each for loop.

How can I make this work?

1 Like

My current solution is to push all of the items into a Vec, clone the Vec, and go from there. I'm wondering whether something better exists.

If you include iter-tools, then I believe that you can use tee.

Thanks for the response.

I took a look at that and it gave me an idea. It looks like what I really want is:

fn foo<TIterator>(items: TIterator)
    where TIterator: IntoIterator<Item = Bar> + Clone {
    for item in items.clone() {
        // use item
    }

    // do other stuff

    for item in items {
        // use item
    }
}

If you want to avoid cloning the entire data structure, you can use IntoIterator by reference.

fn foo<'a, I>(items: &'a I)
    where &'a I: IntoIterator<Item = &'a Bar>
{
    for item in items {
        // use item
    }

    // do other stuff

    for item in items {
        // use item
    }
}

struct Bar;

fn main() {
    foo(&vec![Bar])
}
5 Likes
fn test(mut items: std::slice::Iter<&Unclonable>) {
    items.clone().by_ref().for_each(|x| println!("{:?}", x));
    items.by_ref().for_each(|x| println!("{:?}", x));
}

Please don't revive old threads.