Git Product home page Git Product logo

Comments (8)

lo48576 avatar lo48576 commented on May 23, 2024

Do you mean postorder by "children first"?
If so, you can use traverse() and filtering out NodeEdge::Starts.

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.

floppyhammer avatar floppyhammer commented on May 23, 2024

@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.

lo48576 avatar lo48576 commented on May 23, 2024

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.

floppyhammer avatar floppyhammer commented on May 23, 2024

@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.

lo48576 avatar lo48576 commented on May 23, 2024

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.

floppyhammer avatar floppyhammer commented on May 23, 2024

@lo48576 It surely works! Thank you!

from indextree.

lo48576 avatar lo48576 commented on May 23, 2024

v4.6.0 is released, and now you can write this much more simply as #90 (comment).

from indextree.

LovaTahina avatar LovaTahina commented on May 23, 2024

It works fine! thanks

from indextree.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.