I've got an idea about improving Iterator
. Since it came into my head I started noticing more and more places, where I wished I could use this. I didn't find any trace of anybody proposed it yet, so I'm giving it a shot. What do you think?
Summary
Add Iterator::extend
method, which takes a collection and extend it with iterator's self
.
Motivation
Sometimes there is a need to create a sophisticated iterator and then put all it's items into a collection. Of cource there is Iterator::collect
, which creates a new collection, but there is no convenient method of collecting into an EXISTING one.
Sure, it's possible, but a bit awkward:
fn my_fn(&self, vec: &mut Vec) {
let iter = self.items.iter()
.filter(...)
.enumerate()
.map(...);
vec.extend(iter);
}
or more compact, but way harder to follow:
fn my_fn(&self, vec: &mut Vec) {
vec.extend(self.items.iter()
.filter(...)
.enumerate()
.map(...)
);
}
but nothing beats THIS:
fn my_fn(&self, vec: &mut Vec) {
self.items.iter()
.filter(...)
.enumerate()
.map(...);
.extend(vec);
}
extend
could return the extended collection:
fn my_fn(&self, vec: &mut Vec) -> usize {
self.items.iter()
.filter(...)
.enumerate()
.map(...);
.extend(vec)
.len()
}
Implementation
No rocket science here.
pub trait Iterator {
type Item;
...
fn extend<B, E>(self, extended: B) -> B
where
B: BorrowMut<E>,
E: Extend<Self::Item> {
extended.borrow_mut().extend(self);
extended
}
}
The Borrow
allows passing collections either by value or by reference, which makes it much more elastic.