I have a filtered iterator like so:
let filt_it = a_vector.iter().filter(|x| condition_on_x);
Is there a way I can find out whether it's empty?
I need the iterator to stay an iterator for later use and it doesn't seem possible to clone filtered iterators.
# Create a list of objects but runs out the iterator. l = [_ for _ in iterator] # If the list is not empty then the iterator had elements; else it was empty. if l : pass # Use the elements of the list (i.e. from the iterator) else : pass # Iterator was empty, thus list is empty.
iterators are not reusable; you need to get a fresh Iterator from the Iterable collection each time you want to iterate over the elements.
An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator it are next and hasNext. A call to it. next() will return the next element of the iterator and advance the state of the iterator.
It provide us hasNext() and next() method to work with collection elements. The basic syntax to define the iterate in scala is as follows; valiterate_name = Iterator(value1, value2, value3, so on ....) In this way, we can define an iterate in scala.
You can make your iterator peekable
and peek
the first item; if it's None
, then the iterator is empty. peek
doesn't consume the item1, so the next call to next
will return it. However, peekable
consumes the iterator, so you'll have to pass the Peekable
around — but Peekable
is also an Iterator
, so if your code expects an Iterator
or an IntoIterator
, it'll work fine.
let filt_it = a_vector.iter().filter(|x| condition_on_x).peekable();
if filt_it.peek().is_some() {
// The iterator is not empty, process it.
process(filt_it);
}
Another option is to clone the iterator, call next
once on the cloned iterator; again, if the result is None
, then the iterator is empty. Then, you can process the original iterator, which will yield the first item again.
This option might not always work; not all iterators can be cloned. However, Filter
implements Clone
when both the iterator and the predicate function are Clone
. Starting with Rust 1.26.0, closures implement Clone
when possible (before 1.26.0, closures would never implement Clone
).
Also, this option is probably not viable if the iterator has a side effect, since the side effect may occur twice, or if the iterator is not deterministic, as both copies of the iterator may yield different results.
1 If you call peekable
with a mutable reference to your iterator, you can actually keep the original iterator around after dropping the Peekable
. However, if you had called peek
before dropping the Peekable
, you'll see that it actually consumed the first item in the original iterator. That's completely normal; Iterator
itself doesn't provide an interface for peeking. Peekable
will store the peeked-at item so it can return it in the following call to next
, but if you drop the Peekable
, then that stored item will also be dropped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With