Reputation: 5416
Is there an efficient way to perform a drop_while
for mutable iterators?
Using .take_while()
on its own is insufficient because TakeWhile
is lazy:
let s = String::from("abcdefg");
let mut it = s.chars();
it.by_ref().take_while(|x| *x != 'c');
println!("{:?}", it.next());
This results in a Some('a')
and the following warning:
unused `std::iter::TakeWhile` that must be used
This can be fixed by running a .collect()
which results in the wanted Some('d')
:
let _: String = it.by_ref().take_while(|x| *x < 'c').collect();
But, is this the correct approach? Would this not waste resources?
Upvotes: 0
Views: 1033
Reputation: 58785
You can use skip_while
:
let x = it.by_ref().skip_while(|x| *x <= 'c').next();
println!("{:?}", x); // Some('d')
which is equivalent to using find
, with a negated predicate:
let x = it.by_ref().find(|x| *x > 'c');
println!("{:?}", x); // Some('d')
Upvotes: 2
Reputation: 15135
I believe most iterator methods are lazy except for for_each
which seems to be eager. You can turn your take_while
into a drop_while
like this:
fn main() {
let s = String::from("abcdefg");
let mut it = s.chars();
it.by_ref().take_while(|x| *x != 'c').for_each(drop);
println!("{:?}", it.next()); // prints "Some('d')"
}
Upvotes: 0