rust - Conditionally return empty iterator from flat_map -
given definition foo
:
let foo = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];
i'd able write code this:
let result: vec<_> = foo.iter() .enumerate() .flat_map(|(i, row)| if % 2 == 0 { row.iter().map(|x| x * 2) } else { std::iter::empty() }) .collect();
but raises error if , else clauses having incompatible types. tried removing map
temporarily , tried defining empty vector outside closure , returning iterator on so:
let empty = vec![]; let result: vec<_> = foo.iter() .enumerate() .flat_map(|(i, row)| if % 2 == 0 { row.iter() //.map(|x| x * 2) } else { empty.iter() }) .collect();
this seems kind of silly compiles. if try uncomment map
still complains if , else clauses having incompatible types. here's part of error message:
error[e0308]: if , else have incompatible types --> src/main.rs:6:30 | 6 | .flat_map(|(i, row)| if % 2 == 0 { | ______________________________^ 7 | | row.iter().map(|x| x * 2) 8 | | } else { 9 | | std::iter::empty() 10 | | }) | |_________^ expected struct `std::iter::map`, found struct `std::iter::empty` | = note: expected type `std::iter::map<std::slice::iter<'_, {integer}>, [closure@src/main.rs:7:28: 7:37]>` found type `std::iter::empty<_>`
i know write want nested for
loops i'd know if there's terse way write using iterators.
since rust statically typed , each step in iterator chain changes result new type entrains previous types (unless use boxed trait objects) have write in way both branches covered same types.
one way convey conditional emptiness single type takewhile
iterator implementation.
.flat_map(|(i, row)| { let iter = row.iter().map(|x| x * 2); let take = % 2 == 0; iter.take_while(|_| take) })
if don't mind ignoring edge-case input iterator foo
have more usize
elements use take
instead either 0 or usize::max. has advantage of providing better size_hint()
takewhile
.
Comments
Post a Comment