Comments (8)
Do you mean postorder by "children first"?
If so, you can use traverse()
and filtering out NodeEdge::Start
s.
use indextree::{Arena, NodeEdge};
pub fn main() {
let mut arena = Arena::new();
let n1 = arena.new_node(("1", 0));
let n1_1 = arena.new_node(("1_1", 1));
n1.append(n1_1, &mut arena);
let n1_2 = arena.new_node(("1_2", 1));
n1.append(n1_2, &mut arena);
{
let n1_2_1 = arena.new_node(("1_2_1", 2));
n1_2.append(n1_2_1, &mut arena);
}
let n1_3 = arena.new_node(("1_3", 1));
n1.append(n1_3, &mut arena);
{
let n1_3_1 = arena.new_node(("1_3_1", 2));
n1_3.append(n1_3_1, &mut arena);
let n1_3_2 = arena.new_node(("1_3_2", 2));
n1_3.append(n1_3_2, &mut arena);
let n1_3_3 = arena.new_node(("1_3_3", 2));
n1_3.append(n1_3_3, &mut arena);
}
let iter = n1.traverse(&arena).filter_map(|ev| match ev {
NodeEdge::Start(_) => None,
NodeEdge::End(id) => Some(id),
});
for id in iter {
let (v, level) = arena[id].get();
println!("{}", format!("{:>width$}", v, width = 4 * level));
}
}
output:
1_1
1_2_1
1_2
1_3_1
1_3_2
1_3_3
1_3
1
If you mean reverse order of breadth-first traversal, it should be written manually with dynamically allocated buffers.
from indextree.
@lo48576 Is there any way to modify nodes in the for id in iter
loop? For example, instead of using arena[id].get()
, what if I want to use arena[id].get_mut()
? Which won't compile because we already borrowed arena when calling traverse()
.
from indextree.
I think the crate does not provide direct method to do that, but the below may work (not tested):
// This must return `Some(_)` since the last item to be iterated
// by `.traverse(...)` should be `NodeEdge::End(root_id)`.
let mut next_id = root_id
.traverse(&arena)
.find_map(|ev| match ev {
NodeEdge::Start(_) => None,
NodeEdge::End(id) => Some(id),
});
while let Some(current_id) = next_id {
let current = arena[current_id];
next_id = if current_id == root_id {
// This will be the last node to iterate.
None
} else if let Some(next_sib_id) = current.next_sibling() {
// This will return `Some(_)` since the last item to be iterated
// by `.traverse(...)` should be `NodeEdge::End(next_sib_id)`.
next_sib_id
.traverse(&arena)
.find_map(|ev| match ev {
NodeEdge::Start(_) => None,
NodeEdge::End(id) => Some(id),
})
} else {
// No more following siblings. Go to the parent node.
current.parent()
}
todo!("Do your work here");
}
from indextree.
@lo48576 Unfortunately it doesn't work. The exactly same compile error has been thrown. Just can't have two mutable borrows at the same time if my work is to modify the current node.
from indextree.
Ah sorry, maybe let current = arena[current_id];
is causing error?
// This must return `Some(_)` since the last item to be iterated
// by `.traverse(...)` should be `NodeEdge::End(root_id)`.
let mut next_id = root_id
.traverse(&arena)
.find_map(|ev| match ev {
NodeEdge::Start(_) => None,
NodeEdge::End(id) => Some(id),
});
while let Some(current_id) = next_id {
next_id = if current_id == root_id {
// This will be the last node to iterate.
None
} else if let Some(next_sib_id) = arena[current_id].next_sibling() {
// This will return `Some(_)` since the last item to be iterated
// by `.traverse(...)` should be `NodeEdge::End(next_sib_id)`.
next_sib_id
.traverse(&arena)
.find_map(|ev| match ev {
NodeEdge::Start(_) => None,
NodeEdge::End(id) => Some(id),
})
} else {
// No more following siblings. Go to the parent node.
arena[current_id].parent()
}
todo!("Do your work here");
}
How about this?
from indextree.
@lo48576 It surely works! Thank you!
from indextree.
v4.6.0 is released, and now you can write this much more simply as #90 (comment).
from indextree.
It works fine! thanks
from indextree.
Related Issues (20)
- support no_std HOT 1
- Panic on semantic error, rather than returning error? HOT 3
- Prepend to the node with no children HOT 2
- Should insertions return `Result` type? HOT 4
- Problems around CI stuff HOT 2
- feature request: `remove_children` and `detach_children` HOT 5
- Clarify order of Descendants, Traverse, and ReverseTraverse HOT 2
- Easier access to underlying index HOT 4
- Iterate over Arena in Depth-first order HOT 4
- NodeId::remove_subtree does not remove the whole subtree sometimes HOT 1
- Iterating over all nodes while modifying them HOT 1
- Suggestion: Panic when appending to node that has `self` node as child.
- Appending to tree in parallel HOT 1
- Add Arena::with_capacity HOT 1
- pretty print indextree HOT 1
- bug: `NodeStamp` does not work as expected when reusing nodes
- How to get a node based on NodeId's private index1: NonZeroUsize? HOT 1
- allow getting node using usize as an index.
- Why doesn't arena have a way to iterate over nodeids?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from indextree.