How to iterate correctly all the records of a structure with multiple depth levels in Rust?

3

I would like to know how to iterate correctly in Rust all the results contained in a data structure arranged like this:

struct Node {
    id: i64,
    nodes: Vec<Node>
}

Where records entered in this structure have several levels of depth. Something like:

{id: 1, nodes: [
    {id: 2, nodes: [ 
        {id: 3, nodes: []}, 
        {id: 4, nodes: []},
        {id: 5, nodes: [
            {id: 6, nodes: []},
            {id: 7, nodes: [
                {id: 8, nodes: []},
                {id: 9, nodes: []}
            ]}
        ]}
    ]}
]};

Thanks in advance.

    
asked by anonymous 13.12.2017 / 06:57

2 answers

1

I've created a simple recursive function to deal with the problem. And everything is ok now. I do not know what my misconception was yesterday to create this topic, but I think it was some Rust typing problem.

The real problem I faced was a little different (the structure mentioned) from the question asked, but the essence was the same. And here's my little solution:

use std::vec::Vec;

struct Node
{
       id: i64,
       nodes: Vec<Node>,
       focused: bool
}

struct Controller
{
    focused: i32
}

impl Controller
{
    fn get_focused(&mut self) -> i32
    {
        let nodes: Node = ....; // código suprimido. representado pelo JSON object acima citado, com adição do membro 'focused' na estrtura.

        for node in nodes.iter()
        {
            self.focused = self.node_iterator(node);
        }
        self.focused
    }

    fn node_iterator(&self, node: Node) -> i32
    {
        let mut focused: i32 = 0;

        if node.nodes.len() > 0
        {
            for n in node.nodes.iter()
            {
                if n.nodes.len() > 0
                {
                    focused = self.node_iterator(n);
                    if focused > 0
                    {
                        return focused;
                    }
                }
                else
                {
                    if n.focused == true
                    {
                        focused = n.id as i32;
                        return focused;
                    }
                }
            }
        }
        return 0;
    }
}


fn main()
{
    let mut controller = Controller{focused: 0};

    controller.get_focused();

    println!("{}", controller.focused);
}

If someone knows in some way more elegant to deal with this problem, feel free to share.

    
14.12.2017 / 03:26
0

If the idea is simply to iterate, I think a simpler solution is more valid.

Given the proposed modulation:

struct Node {
    id: i64,
    nodes: Vec<Node>,
}

We can simply construct a function that receives a node (or a list of nodes to support top level lists) and acts on that node. Then the function should follow to the list of nodes internal to the current node, repeating the process.

A flowchart representing this idea is explained below:

Theproposedoneisthenarecursivefunction.Itcouldberepresentedasfollows:

fn parse_nodes(nodes: &Vec<Node>) { nodes.iter() .map(|ref node| { let id = node.id; let len = node.nodes.len(); println!("id: {} - child nodes: {}", id, len); parse_nodes(&node.nodes); }) .count(); }

If we do not care or can not accept lists as the initial argument of the function, we can construct the function as follows:

fn parse_node(node: &Node) {
    let id = node.id;
    let len = node.nodes.len();
    println!("id: {} - child nodes: {}", id, len);

    node.nodes
        .iter()
        .map(|ref node| parse_node(&node))
        .count();
}

With these two solutions we can solve the proposed problem of iterating a structure like the one exposed.

Both solutions could use parallelism elements to shorten the parser runtime. This answer will not address this approach, however. For more information, a good reference is Chapter 16 of The Rust Programming Language ( link ).

    
16.02.2018 / 22:19