Reputation: 6079
I'm trying to collect from a nested iterator and I get a FromIterator
not implemented error. Here's an example:
#[derive(PartialEq)]
enum DayStatus {
Normal,
Abnormal,
}
struct Week {
days: Vec<Day>,
}
struct Day {
status: DayStatus,
}
struct Month {
weeks: Vec<Week>,
}
fn get_abnormal_days(month: Month) -> Vec<Day> {
// assume we have a month: Month which is filled
month
.weeks
.iter()
.map(|w| w.days.iter().filter(|d| d.status == DayStatus::Abnormal))
.collect()
}
fn main() {}
Gives me:
error[E0277]: the trait bound `std::vec::Vec<Day>: std::iter::FromIterator<std::iter::Filter<std::slice::Iter<'_, Day>, [closure@src/main.rs:24:39: 24:74]>>` is not satisfied
--> src/main.rs:25:10
|
25 | .collect()
| ^^^^^^^ a collection of type `std::vec::Vec<Day>` cannot be built from an iterator over elements of type `std::iter::Filter<std::slice::Iter<'_, Day>, [closure@src/main.rs:24:39: 24:74]>`
|
= help: the trait `std::iter::FromIterator<std::iter::Filter<std::slice::Iter<'_, Day>, [closure@src/main.rs:24:39: 24:74]>>` is not implemented for `std::vec::Vec<Day>`
I could try to impl
the FromIterator
but the type it has to be from seems too inner to be deal with. I think I'm not calling the proper collect
or maybe map
but I can't see what I'm missing
My first attempt tried to return &[Day]
but it was failing as well.
Upvotes: 4
Views: 5299
Reputation: 2525
To unnest the iterator, use flat_map
instead of map
.
Furthermore, you need to either use Copy
types or use into_iter
to iterate over owned values and not just references.
Working example:
#[derive(PartialEq)]
enum DayStatus {
Normal,
Abnormal,
}
struct Week {
days: Vec<Day>,
}
struct Day {
status: DayStatus,
}
struct Month {
weeks: Vec<Week>,
}
fn get_abnormal_days(month: Month) -> Vec<Day> {
// assume we have a month: Month which is filled
month
.weeks
.into_iter()
.flat_map(|w| {
w.days
.into_iter()
.filter(|d| d.status == DayStatus::Abnormal)
})
.collect()
}
fn main() {}
Upvotes: 6