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. At first I didn’t find any trace of anybody proposing it, but somebody pointed me to this Rust issue, which is similar, but has different perspective. This was posted originally on Rust users forum. What do you think about this idea?
Summary
Add Iterator::extend_into
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_into(vec);
}
extend_into
could return the extended collection:
fn my_fn(&self, vec: &mut Vec) -> usize {
self.items.iter()
.filter(...)
.enumerate()
.map(...);
.extend_into(vec)
.len()
}
thanks to that the function could conveniently accept collections by both reference or value:
fn my_fn(&self, mut vec: Vec) -> Vec {
self.items.iter()
.filter(...)
.enumerate()
.map(...);
.extend_into(vec)
}
Implementation
No rocket science here.
pub trait Iterator {
type Item;
...
fn extend_into<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.