これらのイテレータは、自分で実装することができます。どのようにfilter
とmap
がstdlibで実装されているかを参照してください。
map_ok
実装:
#[derive(Clone)]
pub struct MapOkIterator<I,F>{
iter:I,
f:F
}
impl<A,B,E,I,F> Iterator for MapOkIterator<I,F>
where F:FnMut(A) -> B, I:Iterator<Item=Result<A,E>> {
type Item = Result<B,E>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|x| x.map(&mut self.f))
}
}
pub trait MapOkTrait{
fn map_ok<F,A,B,E>(self, func:F) -> MapOkIterator<Self, F>
where Self:Sized+Iterator<Item=Result<A,E>>, F:FnMut(A) -> B{
MapOkIterator{iter:self, f:func}
}
}
impl<I,T,E> MapOkTrait for I
where I:Sized+Iterator<Item=Result<T,E>>{}
filter_ok
ほぼ同じである:
#[derive(Clone)]
pub struct FilterOkIterator<I,P>{
iter: I,
predicate: P,
}
impl<I,P,A,E> Iterator for FilterOkIterator<I,P>
where P:FnMut(&A) -> bool, I:Iterator<Item=Result<A,E>> {
type Item = Result<A,E>;
#[inline]
fn next(&mut self) -> Option<Result<A,E>> {
for x in self.iter.by_ref() {
match x {
Ok(xx) => if (self.predicate)(&xx) {
return Some(Ok(xx));
},
Err(_) => return Some(x)
}
}
None
}
}
pub trait FilterOkTrait{
fn filter_ok<P, A, E>(self, predicate: P) -> FilterOkIterator<Self, P>
where Self: Sized + Iterator<Item=Result<A,E>>, P: FnMut(&A) -> bool {
FilterOkIterator{iter: self, predicate: predicate}
}
}
impl<I,T,E> FilterOkTrait for I
where I:Sized+Iterator<Item=Result<T,E>>{}
だからあなたのコードは次のようになります。
["1","2","3","4"].iter()
.map(|x| x.parse::<u16>().map(|a| a+10))
.filter_ok(|x| x%2==0)
.map_ok(|x| x+100)
.collect::<Result<Vec<_>, std::num::ParseIntError>>()
playpen
廃止:
使用take_while
イテレータ:
[Ok(1),Ok(2),Err(3),Ok(4)]
.iter().cloned()
.take_while(|x| x.is_ok())
.collect::<Vec<Result<u32,u32>>>()
//[Ok(1), Ok(2)]
また、あなたがResult
のために実装FromIterator
トレイト使用することができます:あなたはできる多くの方法があります
[Ok(1),Ok(2),Err(3),Ok(4)]
.iter().cloned()
.collect::<Result<Vec<u32>,u32>>()
//Err(3)
[Ok(1),Ok(2),Ok(3),Ok(4)]
.iter().cloned()
.collect::<Result<Vec<u32>,u32>>()
//Ok([1, 2, 3, 4])
http://stackoverflow.com/questions/26368288/dealing-with-result-within-iter? – ArtemGr