There are various solutions to this task. One would be to pass the result as an out-parameter to the function:
fn iter_els<'el>(el_top: &'el El, result: &mut Vec<&'el El>) {
result.push(el_top);
for el in &el_top.children {
iter_els(el, result);
}
}
fn main() {
// build top_el as you did
let mut result = Vec::new();
iter_els(&top_el, &mut result);
println!("{:?}", result);
}
Adapting your original approach imho results in a more complex implementation:
fn iter_els<'el>(prev_result: &Vec<&'el El>) -> Vec<&'el El> {
// Iterate over all elements from a tree, starting at the top-level element.
let mut result = prev_result.clone();
for el in prev_result {
for child in &el.children {
result.push(&child);
}
result.extend(iter_els(&el.children.iter().collect()));
}
result
}
fn main() {
// build top_el as you did
println!("{:?}", iter_els(&vec![&top_el]));
}
Alternatively:
fn iter_els<'el>(prev_result: &'el Vec<El>) -> Vec<&'el El> {
// Iterate over all elements from a tree, starting at the top-level element.
let mut result : Vec<_> = prev_result.iter().collect();
for el in prev_result {
for child in &el.children {
result.push(child);
}
result.extend(iter_els(&el.children));
}
result
}
fn main() {
// build top_el as you did
println!("{:?}", iter_els(&vec![top_el]));
}
As you can see, the first approach only operates on an immutable El
, and one single result Vec
, while the other implementations do not get around clone
and collect
.
Ideally, you would write a custom Iterator
for your tree, but I think this could get quite cumbersome, because this iterator would have to keep track of the current state somehow (maybe can prove me wrong and show that it's actually easy to do).