I have a struct which nests other structs like following:
#[derive(Debug)]
pub struct Rankings {
conferences: Vec<Conference>,
}
#[derive(Debug)]
pub struct Conference {
divisions: Vec<Division>,
}
#[derive(Debug)]
pub struct Division {
teams: Vec<Team>,
}
#[derive(Debug, Clone)]
pub struct Team {
name: String,
market: String,
}
What I want to do is converting a Rankings
instance to Vec<Team>
. Here's my solution:
fn main() {
let mut rankings = Rankings {
conferences: vec![
Conference {
divisions: vec![
Division {
teams: vec![
Team {
name: String::from("Raptors"),
market: String::from("Toronto"),
},
Team {
name: String::from("Knicks"),
market: String::from("New York"),
}
]
},
Division {
teams: vec![
Team {
name: String::from("Bucks"),
market: String::from("Milwaukee"),
},
Team {
name: String::from("Cavaliers"),
market: String::from("Cleveland"),
}
]
},
]
},
]
};
println!("- rankings:\n{:#?}\n", rankings);
let mut raw_teams: Vec<Vec<Vec<Team>>> = rankings
.conferences
.iter_mut()
.map(|c| c.divisions.iter_mut().map(|d| d.teams.clone()).collect())
.collect();
println!("- raw_teams:\n{:#?}\n", raw_teams);
let flattened_teams = raw_teams
.iter_mut()
.fold(Vec::new(), |mut acc, val| {
acc.append(val);
acc
})
.iter_mut()
.fold(Vec::new(), |mut acc, val| {
acc.append(val);
acc
});
println!("- flattened_teams:\n{:#?}\n", flattened_teams);
}
First, I converted Rankings
to Vec<Vec<Vec<Team>>>
using iter_mut()
and map()
, then flattened Vec<Vec<Vec<Team>>>
to Vec<Team>
using iter_mut()
and fold()
.
But I just wrote that code avoiding compile errors, which mean the code could be refactored better using idiomatic patterns. I think I might overuse mutability, and two conversion process can be simplified using appropriate iterator functions. Thanks for any advices.