Keeping things as iterator

I'd like to be able to keep the iterator created as part of collection.filter_map() in a struct for "re-use".

There are a few things that I'm not clear on:

  1. How do you even store an iterator? Box<dyn Iterator<Item=...>> ?
  2. How can you ensure the iterator can be used without consuming the entries? I need to crawl back and forth, keeping the "index"
  3. Is it perhaps easier (even tho probably not idiomatic) to simply use a usize index and keep the collection instead?

Think something like read_dir().filter_map(|e| { .. }) where resulting list would be of Option<String> type. I tried using a

struct MyStruct {
   iter: Box<dyn Iterator<Item=String>>,
}

but the result of the filter_map is an iterator with a closure in the type...

Yes, that's a good way to store an opaque iterator, especially when closures are involved.

Iterator is not designed for this at all.

I think this is probably your best bet. You're basically asking for some kind of "cursor" API, and indexing seems like a fine way to achieve this.

You can totally store an iterator in an Box<dyn Iterator<Item=String>>. The iterator returned from filter_map can be stored in a box using Box::new(filtered_iterator).

If you wish to “keep” the index, you should consider using an iterator which implements Clone. For example, the immutable iterator over a vector or slice can be cheaply cloned. While you cannot crawl back, you can store where you are and keep going in a copy.

Unfortunately the fact that the iterator can be cloned is lost when you put it in a box, so that is not really an option. You can use generics instead: example.